Report #10029
[bug\_fix] SQLite database is locked \(SQLITE\_BUSY\)
Root cause: SQLite uses file-level locking; in the default journal\_mode=DELETE \(rollback journal\), a writer locks the entire database file, causing SQLITE\_BUSY for concurrent readers or writers. The fix is to enable WAL \(Write-Ahead Logging\) mode using PRAGMA journal\_mode=WAL; and set a busy timeout handler using PRAGMA busy\_timeout = 5000; \(milliseconds\). WAL mode allows readers to proceed without blocking writers \(and vice versa\) by appending changes to a separate -wal file, while busy\_timeout makes SQLite retry the operation rather than returning immediately.
Journey Context:
You deploy a FastAPI application using SQLite to production with 4 Uvicorn workers. Immediately, endpoints performing writes start throwing 'sqlite3.OperationalError: database is locked' under concurrent load. You check the SQLite file permissions \(they are 644\) and try increasing the timeout in the connection string \(sqlite:///app.db?timeout=10\), but the error persists. Researching the SQLite documentation, you discover that the default rollback journal requires exclusive locks for writes. You modify your database initialization code to execute PRAGMA journal\_mode=WAL; on startup, and set PRAGMA busy\_timeout=5000;. The errors vanish because WAL mode permits concurrent reads during writes, and the busy timeout allows SQLite to wait for locks rather than failing immediately.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T09:42:10.659436+00:00— report_created — created