Systems · Databases

The Quiet Power of SQLite on the Server

A single-file database has quietly become a serious choice for production servers. Here's what changed in the last few years, what stayed the same, and when reaching for it actually pays off.

Introduction

For most of its life, SQLite was filed away as the "embedded database" — perfect for mobile apps and tiny on-disk caches, but not a serious option for anything bigger. That assumption has quietly fallen apart. A growing number of small-to-medium production apps now run on SQLite as their primary store, and they're not toy projects.

The shift didn't happen because SQLite changed in some dramatic way. It happened because servers, disks, and our expectations about scale all changed around it.

What Changed Recently

Three things mostly. First, NVMe storage made random reads obscenely fast — fast enough that a database "in a file" is no longer a meaningful disadvantage. Second, machines got large enough that a single host can comfortably handle the load that used to demand a fleet. And third, write-ahead logging matured in SQLite, removing one of the long-standing pain points for concurrent reads.

The thing that broke SQLite as a server database used to be concurrent writes. WAL mode and faster disks didn't fix that, but they made it stop mattering for the workloads most apps actually have.

When SQLite Wins

There are three patterns where SQLite is genuinely the right choice, not the scrappy one.

Single-tenant apps

Internal tools, dashboards, B2B apps with one customer per deployment — anything where the database lives next to the app on the same machine. You get sub-millisecond reads with zero network hop, and your "backup strategy" is copying a file.

Read-heavy workloads

Blogs, documentation sites, anything where 99% of traffic is read. WAL mode lets readers and a writer coexist comfortably, and PRAGMA journal_mode=WAL is usually all the tuning you need.

Embedded analytics

For local-first analytical queries — log spelunking, ad-hoc slicing of CSVs — SQLite (often via DuckDB now) is faster than any networked query engine you'd reach for.

When It Doesn't

High write concurrency from many independent processes. Anything that needs a multi-writer setup spanning hosts. Workloads where you actively benefit from row-level locking. In those cases Postgres is still the right tool — and that's fine. SQLite isn't trying to win every category, it's earning a corner of one where it used to be dismissed.

Practical Setup

If you're going to run SQLite for a live service, three settings matter more than the rest:

PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA busy_timeout = 5000;

WAL mode for concurrent reads, synchronous=NORMAL for a sensible durability/throughput trade-off on a single host, and a generous busy timeout so transient lock contention doesn't bubble up as errors.

Closing Thoughts

The point isn't that you should rip out Postgres tomorrow. The point is that "SQLite is for mobile apps" stopped being true a while ago, and a lot of architectures get noticeably simpler when you let yourself consider it.

Sometimes the best infrastructure is the kind that ships as one file and stays out of your way.