keep-daily Buckets by Local DayA Proxmox Backup Server prune policy of keep-daily 7 reads
like "keep a week of backups". It does not mean that. It means "keep the newest snapshot from each of the
last 7 calendar days, in the server's local timezone". If your backups run near local midnight, two
of them land in the same bucket. A host with exactly two backups was one prune away from having one.
PBS prune options are not independent counts of snapshots. Each one defines time buckets and keeps the newest snapshot in each bucket:
keep-last N. The N most recent snapshots, whenever they happened. The only option that
counts snapshots rather than periods.keep-hourly N. Newest snapshot from each of the last N clock hours.keep-daily N. Newest from each of the last N calendar days.keep-weekly, keep-monthly and keep-yearly. The same idea at larger
granularity.A snapshot survives if any option wants it. Here is the consequence people miss. These are calendar buckets, not rolling windows, so two snapshots close together in time compete for the same slot. One of them loses.
A host had exactly two snapshots. A new machine, only just brought into the backup rotation:
2026-08-09T05:49Z
2026-08-10T04:53Z
Nearly 23 hours apart. Two different dates in UTC. Obviously two days of backups.
The backup server's local timezone was UTC−5. In local time:
2026-08-09T05:49Z -> 2026-08-09 00:49 local
2026-08-10T04:53Z -> 2026-08-09 23:53 local <- same local day
Both fell on 2026-08-09 locally. With keep-daily 7 and no
keep-last, PBS saw one day holding two snapshots, kept the newest, and marked the other for
deletion. A host with two backups went down to one, while the policy still read like a week of
retention.
This is not an edge case if your backups run in the early hours UTC. A fleet backing up between roughly 04:30 and 05:50 UTC runs right around local midnight in the Americas. Any of those jobs can straddle a local-day boundary and collide on the next run.
keep-daily with a keep-last floorkeep-last counts snapshots, so it is immune to timezone bucketing. And because a snapshot
survives if any rule wants it, keep-last can only ever retain more, never
delete more. There is no downside beyond a little extra disk.
keep-last=3, keep-daily=7, keep-weekly=4, keep-monthly=6, keep-yearly=1
Adding keep-last 3 across every job fixed the latent version of this on jobs that had run for
months without anyone noticing. After the change, a full prune across five namespaces removed 12 snapshots
out of 530. All genuine same-day duplicates, with every namespace still holding one snapshot per distinct
day.
Prune deletes. Reasoning about bucket semantics is exactly the kind of thing that feels obvious and is not. This whole article is an example. PBS tells you precisely what it intends to do:
proxmox-backup-client prune <group> \
--repository <user@realm!token>@<host>:<datastore> \
--ns <namespace> \
--keep-last 3 --keep-daily 7 \
--dry-run
It prints each snapshot with keep or remove. Read it per group rather than scanning
the total. The total looks reasonable in precisely the case that ruins you. One group losing its only spare
copy is invisible in an aggregate.
--comment field is capped at 128 characters, which is easy to trip over
when scripting job creation with a descriptive note.keep-last. It costs a little disk and
removes an entire class of surprise.keep-daily keeps the newest snapshot per local calendar
day, not per 24 hours, so backups near local midnight collide and prune each other. Pair it with
keep-last, which counts snapshots and can only ever keep more. And dry-run every prune before
you let it loose.