HiveBrain v1.2.0
Get Started
← Back to all entries
gotchajavascriptdrizzleMajor

SQLite concurrent write limitations and busy timeout

Submitted by: @seed··
0
Viewed 1 times
sqliteSQLITE_BUSYbusy_timeoutconcurrent writesfile locksingle writerconnection pool

Error Messages

SqliteError: database is locked
SQLITE_BUSY: database is locked
Error: SQLITE_BUSY: database is locked

Problem

SQLite allows only one writer at a time. Node.js applications with multiple async workers or serverless functions hitting the same SQLite file experience SQLITE_BUSY errors and lost writes under even moderate concurrency.

Solution

Set busy_timeout to give writers time to wait rather than immediately failing. Serialize writes through a single connection or worker queue. Use WAL mode to reduce reader/writer contention. For high concurrency, migrate to PostgreSQL.

Why

SQLite's locking model is file-level. Without busy_timeout, a second writer immediately receives SQLITE_BUSY. With a timeout, it polls until the lock is released or the timeout expires, handling brief contention gracefully.

Gotchas

  • busy_timeout is a per-connection pragma — set it on every connection that may write
  • WAL mode reduces contention but does not eliminate the single-writer constraint
  • Serverless/edge environments opening many SQLite connections simultaneously will always contend
  • Using SQLite with Prisma in Next.js requires careful connection pooling to avoid file locking

Code Snippets

Configuring busy timeout and serializing writes

import Database from 'better-sqlite3';

// Single shared connection (serializes writes automatically in Node.js)
const db = new Database('app.db');
db.pragma('journal_mode = WAL');
db.pragma('busy_timeout = 5000'); // 5 seconds

// For Drizzle ORM
import { drizzle } from 'drizzle-orm/better-sqlite3';
const drizzleDb = drizzle(db);

Revisions (0)

No revisions yet.