wellworn
compare · verified 2026-09-08

Postgres vs SQLite or Turso vs MySQL for a solo developer's web app

pick PostgreSQL 18.6

Postgres 18.6. One process gives you JSONB, full-text search, `LISTEN/NOTIFY`, and a job queue on `SELECT ... FOR UPDATE SKIP LOCKED`, so a solo app can go a long way before it needs a second service. SQLite 3.53.4 in the same container is faster and simpler when exactly one machine writes; the moment you want two app replicas, you are building replication yourself or paying Turso for it.

alternative · SQLite

SQLite, embedded or through Turso, has no network hop and no connection pool. Turso's free plan is 100 databases, 5 GB, 500 million rows read and 10 million rows written per month.

Wins when one machine does all the writing, or you want a separate small database per tenant.

avoid · MySQL

MySQL 8 is a fine database and a poor default here: you give up JSONB operators, partial and expression indexes are newer and narrower, and almost every Postgres-first tool in the TypeScript ecosystem treats it as the second target.

traps for PostgreSQL (1)
severityversionssymptom and fix
major>=9.5.0
Two app replicas both run migrations at boot and the second one fails on an already-applied step.
Run migrations from one place, a release step or a jobs container, and wrap the run in `pg_advisory_lock(<constant>)` so a second process waits instead of racing.
evidence
what your agent receives
VERDICT Postgres vs SQLite or Turso vs MySQL for a solo developer's web app
PICK PostgreSQL 18.6: Postgres 18.6. One process gives you JSONB, full-text search, `LISTEN/NOTIFY`, and a job queue on `SELECT ... FOR UPDATE SKIP LOCKED`, so a solo app can go a long way before it needs a second service. SQLite 3.53.4 in the same container is faster and simpler when exactly one machine writes; the moment you want two app replicas, you are building replication yourself or paying Turso for it.
ALT SQLite: SQLite, embedded or through Turso, has no network hop and no connection pool. Turso's free plan is 100 databases, 5 GB, 500 million rows read and 10 million rows written per month.; wins when one machine does all the writing, or you want a separate small database per tenant
AVOID MySQL: MySQL 8 is a fine database and a poor default here: you give up JSONB operators, partial and expression indexes are newer and narrower, and almost every Postgres-first tool in the TypeScript ecosystem treats it as the second target.
TRAPS (1)
  [1163f1d7] major: Two app replicas both run migrations at boot and the second one fails on an already-applied step.
VERIFIED 2026-09-08 by wellworn reviewer · recheck 2027-01-06 · sources 4