Scheduled backups
How to configure the backup schedule and what the worker does on each run.
Setting the schedule
On the database detail page in the walwarden dashboard, the Schedule section shows the current cron expression. A blank schedule means no automatic backups run.
Enter a cron expression in five-field UTC format:
minute hour day-of-month month day-of-week
Examples:
| Intent | Cron |
|---|---|
| Every hour, on the hour | 0 * * * * |
| Every 6 hours | 0 */6 * * * |
| Daily at 02:00 UTC | 0 2 * * * |
| Every 12 hours (02:00 and 14:00 UTC) | 0 2,14 * * * |
Click Save schedule. The change takes effect immediately; the next backup runs at the next matching tick.
What the worker does on each run
- Claims a
backup_jobrow and transitions it fromqueuedtoclaimed. - Opens a connection to the source database using the stored DSN.
- Starts a
pg_dump --format=custom --compress=9subprocess, streaming stdout to S3 via multipart upload. - Computes a SHA256 checksum of the dump bytes in flight.
- Writes the dump object to S3 at the path
org/<org-id>/db/<db-id>/backup/<YYYY>/<MM>/<DD>/<job-id>.dump. - Writes a manifest JSON to S3 at the same path with extension
.manifest.json. The manifest includes the checksum, size in bytes, Postgres server version, and the job ID. - Signs the manifest with walwarden's Ed25519 private key.
- Re-fetches the manifest from S3 and verifies size, checksum, and canonical body equality.
- Transitions the job to
finalizing, then tocompleted. - Writes a
backup.completedaudit event.
If any step fails, the job transitions to a failed state and a backup.failed audit event is written. The dashboard shows the failure and the error classification.
Audit chain entry
Every backup produces the following sequence of audit events:
backup.queued— scheduler created the jobbackup.claimed— worker claimed the jobbackup.running—pg_dumpsubprocess startedbackup.finalizing— dump uploaded; manifest written; verification in progressbackup.completed— manifest verified; job sealed
You can view the full audit chain on the backup detail page in the dashboard, or export it as part of an evidence bundle.
RPO and loss window
The dashboard hero shows "Last backup: N minutes ago" based on the finalized_at timestamp of the most recent completed backup job. The "You would lose at most N minutes of data" calculation is the elapsed time since that timestamp.
If the scheduled backup fails, the RPO display reflects the last successful backup, not the failed attempt. A failed backup does not advance the RPO bound.