From 20d8d8d4b4109853f3866555b67d258c4ae916d2 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Wed, 25 Mar 2026 23:28:46 -0700 Subject: [PATCH] Set MaxOpenConns(1) to eliminate SQLite SQLITE_BUSY errors Go's database/sql opens multiple connections by default, but SQLite only supports one concurrent writer. Under concurrent load (e.g. parallel blob uploads to MCR), multiple connections compete for the write lock and exceed busy_timeout, causing transient 500 errors. With WAL mode, a single connection still allows concurrent reads from other processes. Go serializes access through the connection pool, eliminating busy errors entirely. Co-Authored-By: Claude Opus 4.6 (1M context) --- db/db.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/db/db.go b/db/db.go index e18457f..2ab1b32 100644 --- a/db/db.go +++ b/db/db.go @@ -59,6 +59,12 @@ func Open(path string) (*sql.DB, error) { } } + // SQLite supports concurrent readers but only one writer. With WAL mode, + // reads don't block writes, but multiple Go connections competing for + // the write lock causes SQLITE_BUSY under concurrent load. Limit to one + // connection to serialize all access and eliminate busy errors. + database.SetMaxOpenConns(1) + // Ensure permissions are correct even if the file already existed. if err := os.Chmod(path, 0600); err != nil { _ = database.Close()