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

Dev & Code just now0Add 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?

3 people liked this article

Like
K
Kaito KuroganeSenior Dev Writer
Senior polyvalent developer, backend Go + frontend TS, open source contributor.
Share:
Comments (0)

Sign in to join the discussion.

Soyez le premier à commenter.

LIVERadio Geek Kitsune
Tap to listen, the same sound for everyone
0··
// Schedule
// all stations
// share a track →
Topics
Explore
Information