pgref.dev/sqlite/errors/SQLITE_BUSY_SNAPSHOT
SQLITE_BUSY_SNAPSHOTWARNINGTier 2 — Caution⚠️ MEDIUM confidence

Busy: WAL snapshot is out of date

Category: LockingVersions: 3.7.0+

🔴 Production Risk Error

Medium — write transactions will be blocked until the read transaction ends.

What this means

SQLITE_BUSY_SNAPSHOT (517) is returned in WAL mode when a read transaction sees an older snapshot and a write transaction cannot proceed because a checkpoint would need to overwrite pages that the read transaction is viewing.

Why it happens

  1. 1Long-running read transaction in WAL mode is blocking the checkpoint.
  2. 2Read connection holds a snapshot that is older than the write connection needs.

How to reproduce

WAL-mode database with concurrent long-running readers and active writers.

trigger — this will ERROR
-- Connection A (read transaction, holds old snapshot):
BEGIN; SELECT * FROM big_table;

-- Connection B (write transaction, blocked):
-- BEGIN; INSERT INTO big_table ... → SQLITE_BUSY_SNAPSHOT
sqlite3.OperationalError: database is locked

Fix 1

Why this works

Shorten read transactions — commit or rollback reads as soon as possible.

Fix 2

Why this works

Use BEGIN IMMEDIATE on writers to detect contention early.

Fix 3

Why this works

Tune WAL checkpoint threshold: PRAGMA wal_autocheckpoint=N

What not to do

Why it's wrong:

Sources

📚 Official docs: https://www.sqlite.org/rescode.html#busy_snapshot

🔧 Source ref: sqlite3.h — SQLITE_BUSY_SNAPSHOT = 517

📖 Further reading: WAL mode

Confidence assessment

⚠️ MEDIUM confidence

Stable.

See also

⚙️ This error reference was generated with AI assistance and reviewed for accuracy. Examples are provided to illustrate common scenarios and may not cover every case. Always test fixes in a development environment before applying to production. Spotted an error? Suggest a correction →