Report #66636
[bug\_fix] SQLite returns 'database is locked' \(SQLITE\_BUSY\) under concurrent write load in DELETE journal mode
Enable WAL \(Write-Ahead Logging\) mode via 'PRAGMA journal\_mode = WAL;'. WAL allows readers to not block writers and vice versa by appending changes to a separate log file rather than overwriting the main database file, eliminating the exclusive writer lock contention of DELETE mode.
Journey Context:
A developer deploys a Flask application using SQLite on Ubuntu with Gunicorn running four worker processes. Under moderate load, writes begin failing with 'database is locked'. The developer initially increases the busy timeout using 'PRAGMA busy\_timeout = 5000' but this only delays the inevitable failure. Checking 'pg\_locks' equivalent \(lsof\) shows exclusive locks on the database file. The developer realizes that the default DELETE journal mode requires an exclusive lock on the entire database file for every write. After reading the SQLite locking documentation, they execute 'PRAGMA journal\_mode = WAL;' on the database. This creates a '-wal' file. Now readers use shared locks on the main database while writers append to the WAL file, allowing concurrent reads during writes. The 'database is locked' errors disappear because writers no longer need exclusive locks on the main database file.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T18:19:49.372910+00:00— report_created — created