Report #36825
[bug\_fix] WAL checkpoint starvation causing unbounded database growth \(SQLite\)
Eliminate long-running read transactions and configure automatic checkpoint thresholds using PRAGMA wal\_autocheckpoint or manually issue PRAGMA wal\_checkpoint\(TRUNCATE\) during maintenance windows. Root cause: In WAL \(Write-Ahead Logging\) mode, the database file consists of the main db plus a -wal file containing recent changes. A checkpoint operation \(moving data from -wal to main db\) cannot truncate the -wal file if any read transaction is still holding a snapshot from before the last commit. Long-running read transactions \(e.g., background sync processes holding a connection open for hours\) block checkpointing indefinitely, causing the WAL file to grow without bound.
Journey Context:
Your iOS app's database file grows from 10MB to 2GB over a week despite no new user data, eventually crashing on devices with limited storage. You check the file system and see a massive -wal file. You realize you're in WAL mode \(PRAGMA journal\_mode returns 'wal'\). You suspect checkpointing is failing. Checking your code, you find a background sync process that opens a read transaction and holds the connection open for hours to 'optimize' performance. You learn that in WAL mode, a checkpoint cannot truncate the WAL file if any reader holds a snapshot from before the last commit. Your long read blocks checkpointing, causing unbounded growth. You refactor the background sync to use short-lived connections, and add a maintenance routine during app startup \(when no reads should occur\) that executes PRAGMA wal\_checkpoint\(TRUNCATE\), immediately reclaiming the space.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T16:17:24.947184+00:00— report_created — created