Report #13481
[bug\_fix] SQLite "database is locked" \(SQLITE\_BUSY\)
Enable WAL \(Write-Ahead Logging\) mode via PRAGMA journal\_mode=WAL and set a busy timeout of 5000ms \(PRAGMA busy\_timeout=5000\); root cause is the default rollback-journal mode requiring exclusive locks for writers, causing readers and writers to block each other under concurrency.
Journey Context:
A FastAPI application using SQLite as the backend database for a medium-traffic internal tool starts throwing "sqlite3.OperationalError: database is locked" errors whenever two users simultaneously submit forms. Initially suspecting file permission issues, the developer checks that the web server user owns the .db file and has write permissions. The error persists. Using the sqlite3 CLI, the developer reproduces the issue: Terminal A begins a transaction with BEGIN IMMEDIATE; Terminal B attempts an UPDATE and immediately gets "database is locked". Checking the database journal mode with PRAGMA journal\_mode; returns "delete", the default. This mode requires an exclusive lock on the entire database file for writes. The application has multiple workers \(gunicorn with 4 workers\), so concurrent writes are inevitable. The fix involves connecting to the database immediately after creation and executing PRAGMA journal\_mode=WAL; followed by PRAGMA busy\_timeout=5000;. In WAL mode, readers do not block writers and writers do not block readers, and the busy timeout allows SQLite to retry acquiring the lock for 5 seconds before returning BUSY, smoothing out brief contention.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T18:50:40.141076+00:00— report_created — created