Backup policies
Reusable schedule + retention + destination templates, and how attachments bind them to your databases.
A backup policy is a named template combining:
- a cron schedule and the timezone it's interpreted in,
- retention rules — how long backups are kept,
- a storage destination — where every archive under this policy lands.
Define a policy once and attach it to many datasources: all production
databases under daily-30day, dev databases under a looser schedule.
Changing the policy changes it for every attached database at once, and
reviewing your backup posture is one screen instead of one per
database.
Policies vs. attachments
The policy itself is org-wide and knows nothing about specific databases. Binding happens through an attachment — one row per (datasource, policy) pair, with two settings of its own:
- Enabled — the per-pair switch. A disabled attachment stays configured but schedules nothing. Shown as the Enabled / Disabled badge on the datasource's policies table; toggled via the CLI or API.
- Priority — a number (lower = higher priority) used where one policy must be chosen for a datasource: Run backup now preselects the highest-priority enabled attachment.
The same policy can't be attached twice to the same datasource; attaching different policies to one datasource is fine and useful — see Attach a policy.
Schedule
Standard 5-field cron (minute hour day month weekday):
| Need | Cron |
|---|---|
| Every day at 03:00 | 0 3 * * * |
| Every 6 hours | 0 */6 * * * |
| Every Monday at 01:30 | 30 1 * * 1 |
| Twice a day at 02:00 and 14:00 | 0 2,14 * * * |
| Every weekday at 23:00 | 0 23 * * 1-5 |
The form translates the expression to plain English as you type, so you can sanity-check before saving.
Timezone. The schedule is interpreted in the policy's timezone —
0 3 * * * in Europe/Prague and the same cron in America/New_York fire
at different UTC times. DST shifts move the schedule with the wall
clock, so "daily at 03:00 local" stays 03:00 local year-round.
How firing works. A scheduler ticks every minute, finds attachments whose next-run time has arrived, and enqueues one backup job per due attachment. Enqueueing is idempotent per (attachment, slot) — a given scheduled slot can never produce duplicate jobs.
Missed windows aren't backfilled. If a slot comes due while the service is down, the database is unreachable, or the attachment is paused, that slot is simply skipped — the next run is always computed forward from the current time. So recovery produces at most one backup, never a burst of one job per missed slot. If you need every window captured, schedule less frequently than your worst-case downtime.
Retention
Two rules, set on every policy:
- Retention days — backups older than this become deletable.
- Keep last N — the floor: the N most recent successful backups per datasource are never deleted, whatever their age.
A backup is deleted only when both rules agree — it's older than
the day window and outside the most-recent-N. Keep-last-N is a
safety floor, not an alternative cap: retentionDays: 30, keepLastN: 7
means "delete after 30 days, but never go below the last 7 backups" —
which matters when a database stops backing up for a while and its
last good backups grow old.
Keeping backups forever. Setting retention days to 0 turns
off age-based deletion entirely — backups under the policy are kept
indefinitely (keep-last-N alone never deletes anything, since it's only
a floor). The dashboard enforces a minimum of 1 day, so 0 is reachable
only through the API or CLI; use it for a
compliance archive you never want auto-pruned, and note that you then
own the resulting storage growth.
The retention worker evaluates policies hourly. Deleted backups stay visible in job history with an Expired badge (the tooltip shows when and under which rule), but their archive is gone and the download action is disabled. Every retention deletion is recorded — the reason and bytes freed — in a permanent retention audit trail.
Behaviour and edge cases
- Editing a policy applies to every attached datasource — as the edit dialog says, "Changes apply to future backup runs only." Schedule changes take effect from the next scheduler tick; retention changes are applied on the next hourly worker pass, which re-evaluates existing backups under the new rules. Tightening retention deletes older backups on that pass — and loosening it later can't bring back what was already deleted.
- Detaching a policy stops future runs for that pair but doesn't delete anything — existing archives keep aging out under the policy's retention.
- Deleting a policy is refused while it's attached to any datasource (a conflict error); detach everywhere first. Historical job records under the policy are preserved.
- The destination is part of the policy and fixed at creation in the dashboard. To move backups to a different destination, create a new policy pointing there, attach it, and detach the old one — existing archives stay where they were written.
Related
- Create a policy — the form, field by field.
- Attach a policy — binding and layering.
- Pause and resume — the two pause levels.