fix: set PRAGMA busy_timeout=5000 to handle concurrent writers#5
Merged
Conversation
SQLite is single-writer. Without busy_timeout, parallel `crm contact add` calls under load (e.g. xargs -P or several agent CLIs writing at once) immediately surface SQLITE_BUSY: DrizzleQueryError: Failed query: insert into "contacts" ... cause: SqliteError: database is locked 5s is enough to ride out any realistic burst. Verified: 40 parallel adds drop from ~4 failures to 0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Repro
SQLite is single-writer. Without
busy_timeout, parallel write calls under load surfaceSQLITE_BUSYdirectly:Easy to reproduce — 30 parallel
crm contact addviaxargs -P10produces ~2/30 failures consistently. Same pattern hits an agent that batches writes or has a daemon + CLI running concurrently against the same DB.Fix
Set
PRAGMA busy_timeout=5000inopenDB. SQLite handles retry/wait internally; concurrent writers block on the lock for up to 5s instead of erroring immediately. 5s is enough to ride out any realistic burst.Test
Added
test/db-busy-timeout.test.ts: spawns 40 parallelcrm contact addprocesses and asserts all 40 succeed with the contact list ending up at length 40.Verified by toggling the PRAGMA off and rerunning.
bun run check-typesclean.bun run buildclean.🤖 Generated with Claude Code