5 — Backups and restores
What a backup is
The complete operational state is the KV store: the per-service probe
rows (current probe, 24-hour ring, 90-day rollups), the vantage rows
and metas, the automation's drafts, the subscribers and their index,
the notification ledger, and the runtime incidents. Secrets never live
in KV — a backup is operator-safe by construction. The document is
versioned (version: 1) and names its source instance (site), so a
restore onto a different instance is visible in the log.
PII note: the document carries subscriber addresses. Store it accordingly — encrypted at rest, access-controlled, and never in git (git is forever).
Taking a backup
- From the admin: the Backups card → Download the backup (the
browser gets
status-backup-<date>.json). - From a shell:
BACKUP_TOKEN=<the OPS_TOKEN> npm run backup(the bearer form is accepted onGET /admin/backupfor automation). - On a schedule:
.github/workflows/backup.ymlruns weekly (and on dispatch) once theOPS_TOKENrepo secret + theSTATUS_BASE_URLrepo variable are declared; the document lands as a 90-day workflow ARTIFACT — never a commit.
Restoring
Upload the document in the Backups card. The restore VALIDATES every key against the known state prefixes (an unknown key is refused: a restore writes state, never arbitrary KV) and MERGES: every row is written, same-key rows overwrite, nothing is deleted — deletion is an explicit per-object operator act (delete an incident, delete a subscriber). The banner reports the written/unchanged counts.
Restoring onto a fresh deployment is the migration path: deploy the new instance, restore the document, and the history carries over. Restoring a document exported from a different instance logs the mismatch — a deliberate operator decision (cloning), never blocked.
What a backup does NOT contain
The instance configuration (it lives in the repo), the secrets (they are re-declared per deployment), and the build-time incident rows (they live in git). Back up the repo for those — which is to say: you already do.