Report #101013
[bug\_fix] sqlite3.OperationalError: database is locked \(SQLITE\_BUSY\)
Enable WAL mode with PRAGMA journal\_mode=WAL; set PRAGMA busy\_timeout=5000 \(milliseconds\) on every connection so writers wait instead of returning SQLITE\_BUSY immediately; keep write transactions short; avoid long-running read transactions while writers are active. WAL allows readers and one writer to proceed concurrently, while busy\_timeout handles transient lock contention.
Journey Context:
You built a Flask/Django prototype with SQLite and gunicorn with 4 workers. Locally everything works, but under any real load you get sqlite3.OperationalError: database is locked. You find suggestions to retry or use a timeout. You first try setting timeout=5.0 in connect\(\), which helps a little but errors still spike during batch writes. Then you inspect the journal mode and see DELETE \(rollback journal\). In rollback-journal mode SQLite uses a single writer lock on the whole database file, so a long SELECT inside one worker blocks an UPDATE in another. You switch to PRAGMA journal\_mode=WAL, which separates readers and writers, and set PRAGMA busy\_timeout=5000 so a writer sleeps briefly if the WAL writer lock is held. The database-is-locked errors vanish because WAL lets readers continue while one writer commits, and busy\_timeout smooths the remaining contention.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-07-06T04:50:34.342010+00:00— report_created — created