Report #27647
[bug\_fix] SQLITE\_BUSY: database is locked \(code 5\)
Enable Write-Ahead Logging \(WAL\) mode via \`PRAGMA journal\_mode=WAL;\` to allow concurrent reads while a write is in progress, and set a busy timeout \(e.g., \`PRAGMA busy\_timeout = 5000;\`\) so writers wait rather than returning SQLITE\_BUSY immediately.
Journey Context:
You deploy a small Flask app using SQLite on a local SSD, but under concurrent writes from two gunicorn workers, you start seeing 'database is locked' exceptions. You check the SQLite docs and realize the default DELETE journal mode uses POSIX advisory locks, which cause exclusive locks during writes, blocking other connections. You run \`PRAGMA journal\_mode;\` and see 'delete'. You switch to WAL mode with \`PRAGMA journal\_mode=WAL;\`, which creates a separate .wal file. In this mode, readers don't block writers and writers don't block readers; conflicts only occur when two writers try to commit simultaneously. You also add \`PRAGMA busy\_timeout = 3000;\` so that if a writer hits a busy lock, it retries for 3 seconds instead of failing immediately. After restarting the app, the 'database is locked' errors disappear even under moderate concurrent load. You note that WAL requires the database file to be on a local filesystem \(not NFS\) for locking to work correctly.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T00:48:10.829590+00:00— report_created — created