Report #37843
[bug\_fix] SQLite database is locked \(SQLITE\_BUSY\) under concurrent writes
Enable Write-Ahead Logging mode via PRAGMA journal\_mode=WAL immediately after opening each database connection, allowing concurrent reads during writes and preventing exclusive database locks.
Journey Context:
Developer builds a Flask application using SQLite for simplicity in an embedded IoT context. Local single-user testing performs flawlessly. Upon deployment to production with four Gunicorn workers handling API requests, intermittent 500 errors appear with sqlite3.OperationalError: database is locked. The errors correlate with high-traffic POST endpoints. Investigation reveals SQLite's default journal\_mode=DELETE uses exclusive locking mechanisms where a writer must obtain exclusive access to the entire database file, blocking other writers and even some readers. The developer attempts to mitigate by adding time.sleep\(\) retries, but this merely masks the issue and degrades performance. Deep reading of SQLite's locking and concurrency documentation leads to the discovery of Write-Ahead Logging \(WAL\) mode. By executing PRAGMA journal\_mode=WAL on database initialization, the storage engine switches to append-only WAL files rather than overwriting the database directly. This allows readers to operate from the original database file while writers append to the WAL, eliminating the exclusive lock contention. The errors vanish because multiple workers can now queue writes without blocking, and readers maintain snapshot isolation without interference.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T17:59:59.666762+00:00— report_created — created