DatabaseSQLiteMongoDB7 min read

Connect a database to your bot

Integrate SQLite, MongoDB or PostgreSQL with your bot to store user data and configurations.


Why use a database?

Without persistence, your bot loses all information on restart. A database lets you store per-server configs, user data, economy systems, warnings and more.

Option 1: SQLite with better-sqlite3

Ideal for small/medium bots. No external server required.

bash
npm install better-sqlite3
javascript
const Database = require('better-sqlite3');
const db = new Database('bot.db');

// Create tables
db.exec(`
  CREATE TABLE IF NOT EXISTS guild_config (
    guild_id TEXT PRIMARY KEY,
    prefix TEXT DEFAULT '!',
    welcome_channel TEXT,
    log_channel TEXT
  );

  CREATE TABLE IF NOT EXISTS warnings (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    guild_id TEXT NOT NULL,
    user_id TEXT NOT NULL,
    moderator_id TEXT NOT NULL,
    reason TEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
  );
`);

// Helper functions
function getGuildConfig(guildId) {
  const stmt = db.prepare('SELECT * FROM guild_config WHERE guild_id = ?');
  return stmt.get(guildId) || { guild_id: guildId, prefix: '!' };
}

function setPrefix(guildId, prefix) {
  const stmt = db.prepare(`
    INSERT INTO guild_config (guild_id, prefix)
    VALUES (?, ?)
    ON CONFLICT(guild_id) DO UPDATE SET prefix = ?
  `);
  stmt.run(guildId, prefix, prefix);
}

Option 2: MongoDB with Mongoose

Ideal for unstructured data and large bots.

bash
npm install mongoose
javascript
const mongoose = require('mongoose');

await mongoose.connect(process.env.MONGODB_URI);

const guildSchema = new mongoose.Schema({
  guildId: { type: String, required: true, unique: true },
  prefix: { type: String, default: '!' },
  welcomeChannel: String,
  autoRoles: [String],
  settings: {
    antiSpam: { type: Boolean, default: false },
    logChannel: String
  }
});

const Guild = mongoose.model('Guild', guildSchema);

// Usage
async function getOrCreateGuild(guildId) {
  let guild = await Guild.findOne({ guildId });
  if (!guild) {
    guild = await Guild.create({ guildId });
  }
  return guild;
}

Option 3: PostgreSQL with Prisma

Ideal for complex relational data and enterprise bots.

bash
npm install prisma @prisma/client
npx prisma init

Define the schema in prisma/schema.prisma:

prisma
model GuildConfig {
  guildId        String   @id
  prefix         String   @default("!")
  welcomeChannel String?
  warnings       Warning[]
}

model Warning {
  id          Int         @id @default(autoincrement())
  guildId     String
  userId      String
  moderatorId String
  reason      String?
  createdAt   DateTime    @default(now())
  guild       GuildConfig @relation(fields: [guildId], references: [guildId])
}
bash
npx prisma migrate dev --name init

Recommended pattern: Cache + DB

javascript
const cache = new Map();

async function getConfig(guildId) {
  if (cache.has(guildId)) return cache.get(guildId);
  const config = await db.getGuildConfig(guildId);
  cache.set(guildId, config);
  return config;
}

Recommendations

  • SQLite for single-server bots or small datasets
  • MongoDB if data is flexible and schema changes often
  • PostgreSQL for complex relations and advanced queries
  • Always use an in-memory cache for frequently accessed data
  • Back up your database regularly

Was this guide helpful?