/config/sqlite/journal-mode-wal
SQLite PRAGMA journal_mode=WAL: concurrent readers and a writer
verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated 2026-10-20
- tool
- SQLite
- file
- the database file (a PRAGMA, run once per database)
- key
- PRAGMA journal_mode
- type
- DELETE | TRUNCATE | PERSIST | MEMORY | WAL | OFF
- default
- DELETE
By default SQLite uses a rollback journal (journal_mode=DELETE): while a writer commits, readers wait. In WAL (write-ahead log) mode, changes are appended to database.db-wal; readers keep reading the last committed state from the main file plus the log, so readers never block the writer and the writer never blocks readers. There is still only one writer at a time.
Turn it on and check it
python - <<'EOF'
import os, sqlite3
db = sqlite3.connect("app.db")
print("default mode:", db.execute("pragma journal_mode").fetchone()[0])
print("new mode: ", db.execute("pragma journal_mode=wal").fetchone()[0])
db.execute("create table t (x)"); db.execute("insert into t values (1)"); db.commit()
print("files: ", sorted(f for f in os.listdir(".") if f.startswith("app.db")))
db.close()
again = sqlite3.connect("app.db") # a new connection: the setting is stored in the file
print("reopened: ", again.execute("pragma journal_mode").fetchone()[0])
EOFOutput
default mode: delete new mode: wal files: ['app.db', 'app.db-shm', 'app.db-wal'] reopened: wal
Unlike most pragmas, journal_mode=WAL is persistent: set it once and every later connection uses it. The -wal and -shm files exist while connections are open and are folded back into the main file at checkpoints and when the last connection closes.
A typical setup for an application
PRAGMA journal_mode = WAL; -- once per database
PRAGMA busy_timeout = 5000; -- every connection: wait up to 5 s for the write lock
PRAGMA synchronous = NORMAL; -- every connection: safe with WAL, fewer fsyncs
PRAGMA foreign_keys = ON; -- every connection: off by defaultLimits
- All processes must be on the same machine: WAL relies on shared memory, so it does not work over network file systems.
- Back up with
VACUUM INTO 'backup.db'or the backup API; copying only the main file while the-walfile has data loses recent commits. - Long-running read transactions stop checkpoints, and the
-walfile grows until they finish.
Sources
Related pages
errors · sqliteSQLite: database is locked (SQLITE_BUSY)SQLite returns database is locked (SQLITE_BUSY) when another connection holds a write lock. Fix it with a busy timeout, WAL mode, and short write transactions.compat · sqliteSQLite feature versions: RETURNING, STRICT, ->> and DROP COLUMNWhich SQLite version added what: DROP COLUMN 3.35, RETURNING 3.35, STRICT tables 3.37, the -> and ->> JSON operators 3.38, unixepoch() 3.38, concat_ws() 3.44.glossary · sqlWhat is a database index?A database index is a sorted structure, usually a B-tree, that finds rows by column value without reading the whole table, at the cost of slower writes.