If you read one line: In 2026 this isn't "toy vs real database." SQLite runs serious production apps now. The decision comes down to two questions — is your write path concurrent, and how much ops do you want to own? Read-heavy, single-region, and you'd rather run zero database servers → SQLite (WAL, plus Litestream/LiteFS or Turso). Concurrent writers, multi-region, or you lean on extensions like pgvector → Postgres (Neon, Supabase, managed). Both scale well past your first paying customers, so pick for shipping speed, not imagined scale.
Why the old answer is wrong now#
For a decade the reflex was automatic: SQLite is what you prototype on, Postgres is what you deploy. That reflex is stale. SQLite is the most-deployed database on earth, and the reason it was "not for production" — clumsy concurrency and no backups story — got fixed at the ecosystem level, not by changing the engine.
Three things closed the gap:
- WAL mode. Write-Ahead Logging lets unlimited readers keep reading while a writer commits. The reader-blocks-writer stalls that made SQLite feel fragile under load mostly disappear.
- Durability and replication as add-ons. Litestream streams your database to object storage continuously; LiteFS (Fly) replicates it across nodes. You get point-in-time recovery and read replicas without running a database server.
- The single-writer wall came down. libSQL and its managed cloud, Turso, add concurrent writes via
BEGIN CONCURRENT(MVCC), reporting up to ~4× stock SQLite's write throughput and killing the dreadedSQLITE_BUSY— plus native vector search for RAG.
The payoff a solo founder feels most: the data lives in your process. No network hop per query means read latency 100–1000× lower than any networked database on the same hardware, and no connection pool to size, no database box to patch at 2 a.m.
The two questions that actually decide it#
Ignore benchmarks — on a single modern NVMe box both are faster than your traffic. Answer these instead.
1. Is your write path concurrent?
Count simultaneous writers, not total writes. A read-heavy app — content, dashboards, a SaaS where users mostly view and occasionally edit — has a light write path, and SQLite in WAL mode handles it comfortably. An app where many users write the same tables at the same instant — collaborative editing, a busy queue, high-rate event ingestion — is what Postgres was built for. If you're between the two, Turso's concurrent writes buy you a lot of headroom before you have to move.
2. How much operational surface do you want to own?
This is the honest tie-breaker, and it's about your time, not the database. SQLite's answer is "almost none" — ship a file, add Litestream, done. Postgres, even fully managed on Neon or Supabase, is one more service with its own dashboard, connection limits, and failure modes. Neither is wrong. But a single founder's scarcest resource is attention, and every managed service is a small, permanent tax on it.
When Postgres is still the right first call#
Reach for Postgres from day one — no cleverness required — when any of these is already true:
- Genuinely concurrent writes are core to the product (not "someday," now).
- Multi-region writes. SQLite replicas are read-only; a single write primary is a hard architectural fact. Postgres has real answers here.
- You depend on extensions — pgvector with HNSW/IVFFlat for serious embedding search, PostGIS for maps, rich full-text. This is often the deciding factor for AI products with heavy vector workloads.
- You want the universal default. Every engineer you might hire knows Postgres. That "boring" value is real: it's the option that never becomes the reason a migration or a new hire stalls.
The decision, in one pass#
Concurrent writers, multi-region, or heavy extensions (pgvector/PostGIS)?
└─ yes → Postgres (Neon / Supabase / managed). Done.
└─ no → Is your write path light and single-region?
└─ yes → SQLite + WAL + Litestream/LiteFS.
Growing write concurrency? → Turso (managed libSQL).
└─ unsure → SQLite now; it migrates to Postgres cleanly later.
The last line is the important one. This is a reversible decision. Keep your SQL reasonably portable, avoid leaning on SQLite-only quirks in hot paths, and moving to Postgres later is a data migration you do in an afternoon when a real constraint appears — not a rewrite. The failure mode isn't "picked the wrong database." It's spending a week choosing when either would have carried you to your hundredth customer. That week is better spent on the thing the database was going to store.
If your product is agent-shaped, the same logic extends to where the agent keeps its state and where its per-task costs land — and to where you run the workloads that write to it. But the database itself? Pick the one that lets you ship this week, and let the second paying cohort tell you if you were wrong.



