Backing up a live SQLite database
Copying the database file while an application writes to it can produce a
copy that is half old and half new. In WAL mode it is worse: recent commits
live in the -wal file, so a copy of the main file alone silently
misses them.
Use the backup API
The sqlite3 shell exposes SQLite's online backup API. It takes
a consistent snapshot while readers and writers keep working:
sqlite3 /var/lib/app/app.db ".backup '/var/backups/app/app-$(date +%F).db'"
Since SQLite 3.27 there is also VACUUM INTO. It writes a
compacted copy, which is handy when the file has accumulated free pages:
sqlite3 /var/lib/app/app.db "VACUUM INTO '/var/backups/app/app.db'"
Check the copy
A backup that has never been opened is a hope, not a backup:
sqlite3 /var/backups/app/app-2026-01-01.db 'PRAGMA integrity_check'
The answer should be a single ok.
Keep a few, not all
find /var/backups/app -name 'app-*.db' -mtime +14 -delete
Two weeks of daily copies is usually enough for a small service. Anything older than that belongs off the machine anyway.