From 0766801552cb4909ff253e0ac869eafb6b40f10b Mon Sep 17 00:00:00 2001 From: Rhys Sullivan Date: Sat, 13 Jun 2026 11:41:46 -0700 Subject: [PATCH] Add busy_timeout to the local libSQL connection Match the self-host open path: a per-connection PRAGMA busy_timeout=5000 gives writers a 5s retry window instead of an instant SQLITE_BUSY when a second OS process transiently holds the write lock (a CLI tool, the v1->v2 migration reader, or a launchd restart racing the old pid). --- apps/local/src/db/libsql.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/local/src/db/libsql.ts b/apps/local/src/db/libsql.ts index d8d82e92f..63844bffd 100644 --- a/apps/local/src/db/libsql.ts +++ b/apps/local/src/db/libsql.ts @@ -26,6 +26,13 @@ export const openLocalLibsql = async (path: string): Promise => { // first enabling. Re-apply both since libSQL gives no shared handle. await client.execute("PRAGMA foreign_keys = ON"); await client.execute("PRAGMA journal_mode = WAL"); + // busy_timeout is per-connection (default 0 = fail immediately on a lock). + // Under the supervised-daemon model a single process owns this file, but a + // second OS process can still transiently hold the write lock (e.g. a CLI + // tool, the v1→v2 migration reader, or a launchd restart racing the old + // pid). Give writers a 5s retry window instead of an instant SQLITE_BUSY. + // Matches the self-host open path (self-host-db.ts). + await client.execute("PRAGMA busy_timeout = 5000"); return client; };