A small service started getting database is locked errors under load. The fix was a one-line change to the busy timeout, but understanding why took longer.
What I learned about SQLite's WAL mode:
- Writers append to a WAL file; readers don't block writers
- Checkpoints move WAL pages back into the main database
- A long-running reader can delay a checkpoint and grow the WAL
That last point explained our problem: an analytics query held a read transaction open, and the WAL grew until the disk alarm fired. We capped the query and moved it to a replica.
I keep coming back to SQLite because the more I learn, the more predictable it gets. That's a rare property in infrastructure.
