Report #9031
[bug\_fix] SQLite3 OperationalError: database is locked
Enable WAL \(Write-Ahead Logging\) mode by executing PRAGMA journal\_mode=WAL; on the database connection. This allows readers to proceed without blocking writers and vice versa, eliminating the exclusive lock contention that causes SQLITE\_BUSY errors under concurrent access.
Journey Context:
A Flask application using SQLAlchemy with SQLite runs fine in development with a single worker, but when deployed to Gunicorn with 4 workers, APIs intermittently crash with OperationalError: database is locked. Debugging reveals that one worker holds an exclusive lock on the main database file during a write, while another worker tries to write, hitting the default 5-second busy timeout. Investigating SQLite locking modes leads to the realization that the default DELETE journal\_mode uses exclusive locking for writes. Switching to WAL mode moves writes to a separate -wal file, allowing concurrent reads and a single writer without blocking readers, which completely resolves the lock contention under multi-worker load.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T07:10:35.139874+00:00— report_created — created