I've been running SQLite on a modest production system for three years now. Not a side project. Real money. Real users. It handles 2-3k req/sec on a single machine with PostgreSQL as cold backup for compliance.
The trick isn't that SQLite is suddenly concurrent. It's that most services don't actually need the concurrency theater of PostgreSQL. I ditched the Postgres instance when I realized 99% of my contention was writes to audit logs. Moved those to a separate sqlite file with WAL mode enabled, problem solved.
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA cache_size = 10000;
Those three settings matter more than the database choice. WAL mode actually handles concurrent reads fine. Writes still serialize but you get async persistence.
Is it right for everyone. No. Distributed systems need Postgres. High-frequency trading needs serious hardware. But if you're a five-person team running a CRUD app, the operational overhead of maintaining Postgres probably costs you more than the database itself. I spend maybe two hours a year on SQLite ops.
The real risk isn't SQLite. It's pretending your problem is bigger than it is.
This tracks with my experience. SQLite's WAL mode genuinely changes the game for write-heavy workloads. I had the same realization with a Go service doing event logging - switched from Postgres and cut operational overhead by half.
The honest truth: your bottleneck is usually application design, not the database. Most teams reach for Postgres because it's the safe choice, not because they measured contention. SQLite forces you to think about access patterns early.
That said, file descriptor limits and backup complexity still bite me occasionally. Worth the tradeoff for your scale, probably not for mine at 10k+ req/sec. The compliance backup thing is smart though.
Chloe Dumont
Security engineer. AppSec and pen testing.
That's honest and worth hearing. The dogma around "SQLite isn't production-grade" does real damage. That said, I'd push back slightly on the audit log setup.
WAL mode helps, but you're still limited to one writer at a time. If your audit logs become a bottleneck later (and they often do under load spikes), you've got nowhere to scale without rearchitecting. Moving to a separate file buys you some breathing room but doesn't solve the fundamental constraint.
For your use case sounds fine. But I'd be explicit about the failure modes you're accepting: no distributed writes, single machine failure, specific backup complexity. Document it so the next engineer doesn't assume it's infinitely scalable.
What does your monitoring actually show for write contention over time.