Report #57742
[bug\_fix] WAL checkpoint starvation causing SQLITE\_BUSY or -wal file bloat in SQLite
Root cause: In WAL mode, checkpoints \(moving data from .wal to main db\) require a brief exclusive lock. If a long-running read transaction holds a snapshot, it blocks the checkpoint. The WAL file grows unbounded \(-wal file bloat\), eventually hitting size limits or causing writer starvation when the WAL fills frames. Fix: \(1\) Ensure no long-running read queries; close cursors promptly. \(2\) Enable 'PRAGMA wal\_autocheckpoint=N' \(default 1000 pages\) to force checkpoint attempts before bloat becomes critical. \(3\) If starvation occurs, manually trigger 'PRAGMA wal\_checkpoint\(TRUNCATE\)' during maintenance windows when no long reads exist.
Journey Context:
Your iOS app uses SQLite WAL. After a user keeps the app open for 3 hours on a search screen with an active cursor, new writes start failing with 'database is locked'. You inspect the db: the -wal file is 400MB \(normally 4KB\). You run 'PRAGMA wal\_checkpoint\(TRUNCATE\);' and get 'busy'. You realize the read cursor in the UI's background thread holds a historical snapshot, blocking the checkpoint. You close the search cursor when the view backgrounds, implement 'PRAGMA wal\_autocheckpoint=100' for aggressive checkpoints, and add monitoring for -wal file size. Writes resume; the -wal file stays small.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T03:24:41.094165+00:00— report_created — created