Report #12780
[bug\_fix] ERROR: database is locked \(SQLITE\_BUSY\) in DELETE journal mode
Execute PRAGMA journal\_mode = WAL; to enable Write-Ahead Logging, and set PRAGMA busy\_timeout = 5000; to allow writers to wait for readers instead of failing immediately.
Journey Context:
You deploy a small Go service using SQLite for a session store. Under moderate load, you see intermittent 'database is locked' errors \(SQLITE\_BUSY\). You check the journal mode with PRAGMA journal\_mode; and it returns 'delete', the default. In DELETE mode, any write operation requires an exclusive lock on the entire database file, blocking all readers and other writers. When two goroutines try to write session data simultaneously, the second one immediately gets SQLITE\_BUSY because it cannot acquire the exclusive lock. You initially try to handle this in the application by catching the error and retrying, but the code becomes complex and racy. You then read the SQLite documentation on WAL mode and realize that WAL allows readers to read from the last committed snapshot while a writer appends new changes to the WAL file, eliminating the need for an exclusive lock on the main database for most operations. You run PRAGMA journal\_mode = WAL; which creates -wal and -shm files. You also add PRAGMA busy\_timeout = 5000; so that if a writer does encounter a brief lock during a checkpoint, it waits up to 5 seconds rather than erroring. After deploying these changes, the 'database is locked' errors disappear, read latency improves because readers no longer block writers, and write concurrency increases significantly.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T16:53:05.583361+00:00— report_created — created