walsnap
Consistent backups for SQLite databases running in WAL mode.
cp db.sqlite backup.sqlite is fine right up until it isn't. In WAL mode the
recent writes live in a separate log file, so the copy opens without complaint and contains
the state of the last checkpoint, not the state of the last commit. Nobody notices until the
day they have to restore.
walsnap takes the online backup, verifies the result with PRAGMA
integrity_check, and can check that a chosen table still has recent rows. It exits
non-zero on anything suspicious, so a cron job or a backup script notices.
Usage
walsnap backup app.db /backups/app-2026-09-14.db
walsnap backup --verify --recent messages:created_at app.db /backups/app.db
walsnap check /backups/app.db
Output is deliberately boring:
checkpoint: 412 pages
copied: 2.1 MiB
integrity: ok
recent: messages, newest 4m ago
Install
go install github.com/kuusela/walsnap@latest
Prebuilt Linux binaries for amd64 and arm64 are on the releases page.
Design notes
- Uses the online backup API, not file copying. A copy that races with a write is a copy that is wrong in a way you cannot see.
- Verification is on by default for
backup. A backup you have not verified is a hope, not a backup. - No configuration file. There are five flags and they fit on one line of
--help. - Exit codes are meaningful: 0 success, 1 usage, 2 source error, 3 verification failed.
Background
Written after a restore that lost a day of writes. The long version is in this post.