Report #25422
[bug\_fix] sqlite3.OperationalError: database is locked
Enable WAL \(Write-Ahead Logging\) mode via PRAGMA journal\_mode=WAL; this allows concurrent readers and a single writer without blocking. Additionally set PRAGMA busy\_timeout=5000. Root cause is SQLite's default rollback-journal uses POSIX advisory locks which fail immediately \(BUSY\) on concurrent write attempts rather than blocking.
Journey Context:
Flask app works perfectly in development \(single-threaded werkzeug\) but in production with 4 gunicorn workers, any POST that writes to SQLite immediately throws "OperationalError: database is locked". Initial attempt to add retry logic with exponential backoff fails because the default busy\_timeout is 0, causing immediate failure. Checking the database with sqlite3 cli reveals journal\_mode=delete. Switching to WAL mode allows reads to proceed during writes, and the lock contention disappears, though the app must now handle -wal and -shm files in the backup strategy.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T21:04:38.785216+00:00— report_created — created