Report #58348
[bug\_fix] SQLITE\_BUSY: database is locked during WAL mode checkpoint starvation
Avoid long-running read transactions in WAL mode; fetch all required data into application memory and close the transaction immediately. Alternatively, use \`PRAGMA busy\_timeout = 60000\` to allow writers to wait for readers to finish. For long analytical queries, consider creating a separate read-only connection pool with \`PRAGMA query\_only = 1\` and ensuring checkpointing happens during low-activity windows using \`PRAGMA wal\_checkpoint\(RESTART\)\` manually.
Journey Context:
A data pipeline uses SQLite in WAL mode for concurrent ETL operations. A scheduled job begins a long-running SELECT query to generate a daily report, iterating over millions of rows. While this read transaction is open, write operations \(INSERTs from streaming data\) begin failing with 'SQLITE\_BUSY: database is locked'. The developer is confused because WAL mode is supposed to allow concurrent reads and writes. Investigating with \`PRAGMA wal\_checkpoint\`, they find the checkpoint is blocked and the WAL file is growing indefinitely. They realize that in WAL mode, a long-running read transaction prevents the checkpoint operation from completing because the checkpoint cannot move past the oldest active transaction. Eventually, when a write operation triggers a checkpoint or needs to wait for the WAL to be checkpointed, it blocks on the long read. The solution is to restructure the application to avoid holding read transactions open during long processing. The application fetches the data into memory using a short-lived connection/transaction, closes the connection to release the WAL lock, then processes the data. For cases where long reads are unavoidable, they implement a separate connection with \`PRAGMA busy\_timeout = 60000\` to allow the write to wait, and they schedule explicit checkpoints during maintenance windows.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T04:25:45.368984+00:00— report_created — created