SQLite in production: what Julia Evans learned from running it for real

Dev & Code Jul 18, 2026Add to bookmarks

SQLite in production: what Julia Evans learned from running it for real
Illustration : Momiji Shirogane

Julia Evans publishes her notes on SQLite: nothing spectacular, but all very useful for those hesitating to run a real app on this small file.

The concrete case

Julia Evans - whose zines and articles have educated a generation of devs about Linux internals, HTTP, DNS - published on her blog jvns.ca on July 17, 2026, a post titled « Learning a few things about running SQLite ». It's neither an introductory tutorial nor a religious plea: it's a field notebook of someone who put SQLite into production on their own service and notes what surprised them. A delight.

What we learn

We won't spoil the article - go read it, it's in English but short -, but a few points come up regularly in SQLite production debates and deserve to be recalled here for the curious:

1. WAL mode: essential for concurrency

By default, SQLite uses the DELETE journal mode, where writes block reads. In WAL (Write-Ahead Logging), reads no longer block writes and vice versa:

PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;

synchronous = NORMAL (instead of FULL) accepts to lose at most the last transaction in case of a sudden power cut, in exchange for a massive performance gain. This is what Litestream and most modern SQLite servers do.

2. One writer connection, multiple readers

Unlike PostgreSQL, SQLite does not parallelize writes. A classic pattern in Rust or Go: a single connection reserved for writing, a pool of connections for reading. This is the model of the crate rusqlite combined with deadpool-sqlite with this separation, or the Go lib mattn/go-sqlite3 with sql.DB configured SetMaxOpenConns(1) for writing.

3. Live backups: Litestream or LiteFS

Backing up an SQLite file "by copying" while a transaction is in progress is the best way to have a corrupted backup. Two tools reign:

  • Litestream (by Ben Johnson, also author of BoltDB): continuously replicates to S3, Backblaze B2 or GCS. Streaming of the WAL, fast restore.
  • LiteFS (same author, now at Fly.io): goes further, multi-node replication with reading from any replica.

4. The real SQLite ceiling in 2026

SQLite handles tens of thousands of queries per second on a single file without flinching, provided it's in WAL and well indexed. The real ceiling is not SQL, it's the disk: local NVMe >> network disk, EBS gp3 >> EFS. Many SQLite failures in production come from putting the file on a network share (NFS in particular - SQLite explicitly discourages this in bold in its doc sqlite.org/faq.html#q5).

To remember

Julia Evans' point of view, as always, is: try, measure, write what you find. No "SQLite scales" or "you need Postgres for anything real". Just: this behavior surprised me, here's why, here's what I changed.

For any dev who hesitates to pull out the big relational artillery for a single-server app or a side project, this kind of article is worth a hundred synthetic benchmarks.

À tester chez vous

The query `SELECT * FROM pragma_compile_options;` returns the list of flags with which your SQLite binary was compiled. On Debian/Ubuntu, `SQLITE_ENABLE_FTS5` (full-text search) is often missing. Check before basing an app on it.

Resources, try it

Article produced by artificial intelligence, reviewed under human editorial control.

Our newsroom
Was this article helpful?

8 people liked this article

Like
K
Kaito KuroganeSenior Dev Writer
Senior polyvalent developer, backend Go + frontend TS, open source contributor.
Share:
LIVERadio Geek Kitsune
Tap to listen, the same sound for everyone
0··
// Schedule
// all stations
// share a track →
Topics
Explore
Information