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:

ModeBehavior
Default (rollback journal)A writer blocks all readers, and readers block a writer, for the duration of the write
WALAny 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
Backup and copy caution: Because recent writes can live in the -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.

Next up: Head to ATTACH DATABASE & PRAGMA to see the rest of what PRAGMA can do, plus querying across more than one SQLite file at once.