WAL Mode & Concurrency
Picture RecipeBox as a mobile app: a background job is syncing new recipes down from the server while the user is simultaneously scrolling their recipe list on screen. In SQLite's default journal mode, a writer blocks readers (and readers block a writer) for the duration of the write — on a slow sync, that's a UI that visibly freezes. WAL mode is SQLite's fix for exactly this kind of concurrent access.
Enabling WAL Mode
PRAGMA journal_mode = WAL; switches a database from the
default rollback-journal mode to Write-Ahead Logging. It's set per database file and
persists across connections once enabled.
PRAGMA journal_mode = WAL;
-- Confirm it took effect
PRAGMA journal_mode;
-- Output: wal
What Changes: Readers Don't Block Writers
In WAL mode, writes are first appended to a separate write-ahead log file instead of being written directly into the main database file. This means:
| Mode | Behavior |
|---|---|
| Default (rollback journal) | A writer blocks all readers, and readers block a writer, for the duration of the write |
| WAL | Any number of readers can run concurrently with a single writer — readers see a consistent snapshot and are never blocked by the write in progress |
SQLite still only allows one writer at a time in either mode — WAL doesn't give you multiple simultaneous writers — but it removes the reader/writer blocking that causes noticeable stalls in apps with any concurrent access.
The Extra -wal and -shm Files
WAL mode creates two extra files alongside your main database file, both required for it to work:
-- If your database file is:
recipebox.db
-- WAL mode also creates:
recipebox.db-wal -- the write-ahead log itself (pending writes)
recipebox.db-shm -- shared-memory index used to coordinate readers/writer
-wal file rather than the main .db file, copying just recipebox.db
while WAL mode is active can silently miss committed data. Either checkpoint first (SQLite does this
automatically at intervals, or you can run it manually), or copy all three files together.When It's Worth Enabling
WAL mode is generally recommended for any app with concurrent access to the same database — exactly the mobile-sync scenario RecipeBox illustrates: a background sync writing new recipes while the UI thread reads the current list. For a strictly single-connection, single-threaded use case, the default mode is simpler and WAL's benefit disappears.
PRAGMA can do, plus querying across more than one
SQLite file at once.