SQLite or Postgres for Your Bot? One Question Decides It

·5 min read·Updated
sqlitepostgresdatabasesbotsarchitecture

The usual advice is "start with SQLite and move to Postgres when you outgrow it," which is fine but answers the wrong question. On a container platform the decision isn't about scale, it's about how many processes need the data. If your bot is a single process, SQLite on a volume is the better choice by a distance — no second app, no allocation taken from your quota, nothing exposed to the internet, and a backup you can download in one click. If a second app needs the same data — a web dashboard, a worker, a second bot — SQLite stops being an option entirely, because volumes belong to exactly one application and cannot be shared. That's the whole decision.

Why volume sharing settles it

A volume is attached to one app. There's no mechanism to mount the same volume into two applications, so two containers cannot read and write the same SQLite file — and even if they could, SQLite's locking assumes a single machine's filesystem, not two processes coordinating across a network.

So the rule is mechanical rather than a matter of taste:

Who needs the data Answer
One process (a bot on its own) SQLite on a volume
Two or more apps Postgres — there's no alternative

Everything below is just the consequences.

What SQLite actually costs you here: nothing

For a single bot, SQLite isn't a compromise — it's the option with fewer downsides:

The single caveat is the one everybody knows: one writer at a time. For a bot that's one process handling events sequentially, that limit is theoretical.

What Postgres costs you here

It's a good database and this platform runs it fine — there's a one-click template. But be clear-eyed about the price on a small account:

  • An allocation slice. It's a second app with its own CPU and RAM, taken from the same account limits.
  • A public endpoint. There's no private networking, so your bot reaches its database over a publicly reachable TCP port with credentials as the only boundary. That's manageable but real — a long random password, and remove the binding when you're not using it.
  • Your own backups. Self-hosted Postgres means pg_dump on a schedule and shipping it somewhere else, rather than a file you can click to download.
  • A second thing that can be down. Your bot now has a dependency that starts, stops, and fails independently of it.

None of that is a reason to avoid Postgres when you need it. It's a reason not to reach for it by default.

The cases that genuinely need Postgres

Be honest about these rather than pretending SQLite scales forever:

  • A dashboard alongside your bot. The most common one. Two apps, one dataset, no shared volume — Postgres.
  • Multiple writers. A bot plus a worker both writing, or a sharded bot with several processes.
  • Concurrent write pressure. A high-traffic bot logging every message will meet SQLite's single-writer limit for real, not theoretically.
  • You want the data to outlive the app. A volume belongs to its app; a separate database app can be rebuilt independently.
  • Queries SQLite handles badly — heavy joins over large tables, or features you specifically want from Postgres.

Migrating later is fine

Choosing SQLite now doesn't trap you. If you use an ORM or query builder, the switch is mostly a connection string and a migration; if you wrote raw SQL, most of it ports with minor dialect changes.

What makes the migration painful isn't the database — it's discovering you need it during an incident. So the useful preparation is cheap: keep your data access in one place rather than scattered through command handlers, and take a backup before you start. Then "we need Postgres now" is an afternoon rather than a rewrite.

If you do move, rehearse it on a staging app with a copy of real data. A migration that only ran against an empty database hasn't been tested.

FAQ

Should my Discord bot use SQLite or Postgres?

SQLite if the bot is the only process touching the data. Postgres if a second app — a dashboard, a worker — needs the same data, because volumes can't be shared between apps.

Can two apps share a volume?

No. A volume belongs to one application, so two containers can't read and write the same SQLite file.

Isn't SQLite too limited for production?

Not for a single-process bot. The main constraint is one writer at a time, which a single event-handling process doesn't hit. Concurrent writers are the real reason to move.

Does running Postgres cost extra?

It takes CPU and RAM from your account allocation, and you own its backups. The number of apps doesn't itself change the bill, but the resources it reserves do.

Is my Postgres exposed to the internet?

Yes — there's no private networking, so it's reachable on a public port protected by credentials. Use a long unique password and remove the port binding when it isn't needed.

How hard is migrating from SQLite to Postgres later?

Usually straightforward, especially with an ORM. Keep data access in one module now and it stays an afternoon's work rather than a rewrite.

Wrapping up

"Start simple and scale later" is good advice that people apply to the wrong axis. The thing that forces Postgres isn't how much data you have — it's a second process needing to see it, which on this platform is a hard architectural boundary rather than a performance threshold. One process, one file, one volume is genuinely the right answer for most bots, and it stays the right answer far longer than the conventional wisdom suggests.