How to use a database with your Discord bot: SQLite, PostgreSQL and MySQL
Sooner or later a bot needs to remember something: a member's level, a server's chosen prefix, a reminder, a ticket number. Variables in memory vanish at every restart, and plain text files stop working the moment two things try to write at once. A database is the sturdy answer. This guide helps you choose one, set it up and avoid the mistakes that corrupt data or freeze your bot.
What to store, and where not to
Store things that must survive a restart: per-server settings, user progress, reminders, moderation records, ticket data.
Do not store:
- Your bot token or other secrets. Those belong in environment variables. See How to create a Discord bot and keep its token safe.
- Things you can recompute cheaply, such as the current time.
- Message content and personal data you do not need. Less stored means less to protect and less to explain.
The three common choices
| Database | Best for | Main trade-off |
|---|---|---|
| SQLite | Small and medium bots, one process | A single file, so only one program should write at a time |
| PostgreSQL | Larger bots, many writes, sharding, reporting | Needs a separate database server to run |
| MySQL or MariaDB | Same as PostgreSQL, widely available on hosts | Also needs a server and a login |
SQLite is the right starting point for most bots. There is nothing to install or manage. The database is one file in your bot's folder, and it handles thousands of reads and writes comfortably. Back up that file regularly, and you have backed up your bot.
Move to PostgreSQL or MySQL when you outgrow it: when several processes must write at once, such as with sharding, when you need queries over a lot of data, or when you want to share data with a website or dashboard.
Using SQLite well
- Use an async library in Python. The standard
sqlite3module is blocking, so a slow query freezes your whole bot.aiosqliteruns queries without stopping the event loop. - In Node.js, libraries differ.
better-sqlite3is fast but synchronous, so keep queries short. Others use callbacks or promises. - Keep the file in a persistent place. On a managed server, files in the bot's folder survive restarts. Check that your database is not written to a temporary directory.
- Turn on write-ahead logging with
PRAGMA journal_mode=WAL. It improves concurrency and robustness. - One writer. Do not have two programs, or two copies of your bot, writing to the same file.
Using a server database
You need a host, a database name, a user and a password. Put them in environment variables, never in code, as in Environment variables and keeping your bot token safe.
Good habits:
- Use a connection pool. Opening a new connection for every command is slow. A pool reuses a handful.
- Use a library built for async. In Python,
asyncpgfor PostgreSQL oraiomysqlfor MySQL. In Node.js,pgormysql2. - Create a database user with only the access the bot needs, not the owner account.
- Keep the database off the public internet when you can, or restrict which addresses may connect.
If you run your own database on a VPS, How to install and secure MariaDB and Set up PostgreSQL on Ubuntu walk through it.
Safe queries
Never build a query by pasting user text into a string. That is how SQL injection happens, where a clever input turns into a command. Always use parameterised queries, where the library puts the value in separately:
SELECT level FROM users WHERE id = ?
Libraries use ?, $1 or %s as placeholders, depending on the database. The value is supplied alongside, and it cannot change the query's structure. This single habit prevents the worst database bug there is.
Designing tables
Keep it simple at first:
- One table per kind of thing: users, servers, reminders.
- A clear primary key, often the Discord ID, stored as text or a 64-bit integer. Discord IDs are bigger than some languages' default integers, so be careful not to lose precision, in JavaScript especially, where large numbers should be handled as strings.
- Timestamps for when rows were created.
- Indexes on columns you search by, such as the user ID.
Write down your table layout in a file, and keep each change as a small migration script. It lets you update the database layout without losing data.
Backups
A bot's database is often its most valuable asset. Back it up on a schedule, and keep copies away from the server. For SQLite, copy the file while the bot is idle, or use the database's backup command. Creating and restoring backups shows the panel's tools, and The 3-2-1 backup rule explains the principle.
Common mistakes
- Blocking queries that freeze the bot. Use async drivers.
- No backups, until the day the file is lost.
- Storing secrets in the database.
- Running two copies of the bot that write to the same SQLite file.
- Forgetting to close or release connections, which eventually exhausts the pool.
- Keeping data forever with no reason. Delete what you no longer need.
Start small, with SQLite, and keep your queries safe. You can move to a larger database later without changing the rest of your bot very much.
Still stuck? Open a ticket on Discord - run /ticket in any channel, pick a department, and include your Server ID or Invoice ID so we can jump straight in.