Report #52646
[bug\_fix] database is locked \(SQLITE\_BUSY\) with default DELETE journal mode
Enable Write-Ahead Logging \(WAL\) mode using PRAGMA journal\_mode=WAL, and/or set a busy timeout using PRAGMA busy\_timeout=5000. The root cause is that SQLite uses POSIX advisory locking on the database file. With the default DELETE journal mode \(rollback journals\), exclusive locks are held for the entire transaction duration. If process A holds a read lock and process B tries to write, or if two writers contend, SQLite returns SQLITE\_BUSY immediately unless configured otherwise. WAL mode allows readers and writers to proceed concurrently \(snapshot isolation\), drastically reducing lock contention. The busy timeout pragma causes SQLite to retry with exponential backoff rather than returning immediately.
Journey Context:
A Python Flask application uses SQLite for a small web service. Under light load it works fine, but when two users submit forms simultaneously, one gets 'sqlite3.OperationalError: database is locked'. The developer checks the code: each request opens a connection, does INSERT, commits, closes. They search online and find conflicting advice about threads. They check that Flask is running single-threaded in development, but the error persists. Examining the file system, they notice a .db-journal file appears briefly during writes. They learn that SQLite locks the entire database file during writes in DELETE journal mode. Since one request holds the lock for the duration of the transaction, if another request comes in, it gets SQLITE\_BUSY. The developer tries setting PRAGMA busy\_timeout=3000, which helps some requests wait, but under sustained load, they still get timeouts. The definitive fix is enabling WAL mode: PRAGMA journal\_mode=WAL. After enabling WAL, they test concurrent writes: WAL allows readers to read from a snapshot while a writer appends to the WAL file, eliminating the exclusive lock contention. The 'database is locked' errors disappear completely, and read performance improves because reads don't block writes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T18:51:46.053609+00:00— report_created — created