SQLite Concurrency

SQLite Error: Database Is Locked (Fix Guide)

Fix SQLite database is locked error. Covers WAL mode, busy timeout, concurrent access patterns, and write locking strategies.

Mar 12, 2026 5 min read

The Error Message

database is locked

What Causes SQLite SQLITE_BUSY?

SQLite "database is locked" error (SQLITE_BUSY) occurs when one process holds a write lock and another process tries to write (or sometimes read) at the same time. SQLite allows only one writer at a time.

Common Causes

Concurrent writes

Two processes or threads trying to write to the database simultaneously.

Long-running transaction

A transaction holds a write lock for too long, blocking other processes.

WAL mode not enabled

Default rollback journal mode is more restrictive than WAL mode.

Unclosed database connection

A crashed process left a lock file behind.

How to Fix It

Step 1: Enable WAL mode

WAL (Write-Ahead Logging) mode allows readers to proceed while a writer is active. This is the single most impactful fix.

-- WAL allows concurrent reads during writes:
PRAGMA journal_mode=WAL;

-- Verify:
PRAGMA journal_mode;  -- should return 'wal'

Step 2: Set busy timeout

Instead of failing immediately, busy_timeout makes SQLite wait for the specified time before returning SQLITE_BUSY.

-- Wait up to 5 seconds for the lock to clear:
PRAGMA busy_timeout = 5000;

-- In Python:
import sqlite3
conn = sqlite3.connect('mydb.db', timeout=5)

-- In Node.js (better-sqlite3):
const db = new Database('mydb.db', { timeout: 5000 });

Step 3: Keep transactions short

Keep write transactions as short as possible. Do data processing outside the transaction, then write in a quick batch.

-- Bad: long transaction
BEGIN;
-- ... lots of work ...
COMMIT;

-- Better: batch writes
BEGIN;
INSERT INTO logs VALUES (1, 'event1');
INSERT INTO logs VALUES (2, 'event2');
INSERT INTO logs VALUES (3, 'event3');
COMMIT;

Step 4: Remove stale lock files

If a process crashed, it may have left a lock file. Only delete it if no other process is using the database.

-- Check for lock files:
ls -la mydb.db*
-- mydb.db
-- mydb.db-wal    (WAL file)
-- mydb.db-shm    (shared memory)
-- mydb.db-journal (rollback journal)

-- If no processes are using the database:
-- Delete the journal/lock file
rm mydb.db-journal

How to Prevent This Error

Always enable WAL mode for production SQLite databases. Set busy_timeout to at least 3-5 seconds. Use a single database connection pool in your application. Consider PostgreSQL if you need heavy concurrent writes.

Fix SQLite Errors with AI2SQL

Instead of debugging SQL syntax manually, describe what you need in plain English and let AI2SQL generate the correct query for SQLite.

Try AI2SQL Free

No credit card required

Frequently Asked Questions

Why does SQLite say database is locked?

SQLite allows only one writer at a time. If another process is writing, your operation must wait. Enable WAL mode and set busy_timeout to handle this gracefully.

What is WAL mode in SQLite?

WAL (Write-Ahead Logging) mode allows readers to continue while a writer is active, significantly reducing lock contention. Enable it with PRAGMA journal_mode=WAL.

When should I use SQLite vs PostgreSQL?

Use SQLite for single-user apps, embedded systems, and development. Switch to PostgreSQL when you need concurrent writes from multiple processes, or when your data exceeds a few GB.

Stop Debugging SQL Errors Manually

Describe what you need in plain English. AI2SQL generates correct SQLite queries instantly.

Try AI2SQL Free

No credit card required