The Updates page now tells you what auto-backup actually contains, and offers an opt-in DB snapshot. A note at the top of the page is explicit about the mental-model gap that v3.4.34 codified: the per-apply .backups/<timestamp>/ directory holds code and templates only, not a copy of the database. For users who want a consistent DB snapshot tied to a specific apply, a new "Snapshot database with this apply" checkbox writes one through SQLite's online-backup API into the same backup directory — the only correct way to snapshot a live SQLite database, never the racy file-copy that pre-v3.4.34 attempted. Off by default because the snapshot is the size of the live database (can be gigabytes) and the live DB itself stays in place untouched either way; opting in is an informed-consent choice, especially on installs running near their disk-headroom limits.
-
Both apply paths honor the checkbox. The local-apply ZIP flow and the GitHub-apply flow both read the same checkbox via a shared
getSnapshotDbFlag()helper and append?snapshot_db=trueto their fetch URL when checked. The endpoint defaults tofalsewhen missing, so a cached page or older template gracefully degrades to pre-v3.4.38 behavior. -
Snapshot failures don't block the update apply. If the snapshot step fails for any reason — disk full, permissions, source DB corruption — the failure is logged at WARNING level but the apply continues. The reasoning: the user opted in to belt-and-suspenders behavior, and losing the suspenders shouldn't prevent putting the belt on. The update's code-only backup still happens, and the live DB stays in place (PRESERVE_PATHS skips it). Worst case is no DB rollback for this specific apply.
-
Page navigation: the doc note links to Configuration → Backup so users who want the full-strength backup feature (zip with manifest + config + DB) can find it without ambient knowledge of where it lives.
Behind the scenes
- The snapshot step lives in
apply_local_updatebetween the code-backup-loop completion and the prune. That placement means the snapshot is included in the keep-5 retention policy (prunes happen after) and its failure can't block routine apply (the apply's response on backup failure returns 500 before this point is reached). - File naming:
<live_db_filename>.snapshot(e.g.aircraft_history.db.snapshotoraircraft_history_synthetic.db.snapshot). Lives at the top level of.backups/<timestamp>/so a user inspecting the backup dir sees the snapshot sibling-of-its-source. - Uses
_open_db_connfromcollectorfor both source and destination, so the snapshot inherits the same WAL/journal pragmas the live DB uses. Thedst.backup()call inside awith dst:block gives the standard transactional semantics SQLite documents for its online-backup API. - The pre-apply settings card is a real
<div class="card">styled to match the existing card grammar on the page, not a banner — keeps the page rhythm intact, and gives the checkbox a comfortable parking spot that doesn't compete with the GitHub-update / Local-zip / ntfy-update cards below it.
Operational notes
- No schema changes; no config changes; no new endpoints. The
snapshot_dbquery parameter is additive on both existing apply endpoints. - The DB-snapshot step does NOT prune old snapshots beyond the existing
INSTALL_BACKUP_KEEP=5retention that applies to the whole.backups/<timestamp>/directory tree. If you check the box on every apply, your.backups/will grow by 5× the live DB size and stabilize there. On the test box at 0.29× disk headroom, leave the box unchecked unless you've planned the space.