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.
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.
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.