Multiple snapshots kept per year

When I run restic forget, the reasons column shows why a given snapshot is kept (and not forgotten/removed). Why is there more than one snapshot with the reason “yearly snapshot”?

$ restic forget --dry-run -l 10 -d 7 -w 4 -m 12 -y 9 --group-by host
Applying Policy: keep 10 latest, 7 daily, 4 weekly, 12 monthly, 9 yearly snapshots
keep 15 snapshots:
ID        Time                 Host        Tags         Reasons           Paths
-------------------------------------------------------------------------------------------------
3d2f2da4  2021-10-26 20:52:18  machine     work         monthly snapshot  /home/me/work
                                                        yearly snapshot
e06f9ced  2021-11-15 16:32:40  machine     work         monthly snapshot  /home/me/work
                                                        yearly snapshot
7c64fa24  2022-09-30 22:30:56  machine     work,auto    monthly snapshot  /data/me/work
d0e5ffd3  2022-10-04 22:38:09  machine     work         monthly snapshot  /data/me/work
...

My understanding was that as the snapshot e06f9ced from November 2021 is the last of 2021. So the snapshot 3d2f2da4 from October 2021 is not needed as a yearly snapshot. Why does restic decide differently?

1 Like

Is the year counted as calendar year or from today one year back in time (2022-12-10 to 2023-12-10)? In the latter case the output makes sense. I just always thought in calendar years (same for days, weeks and months).

Hm, the docs say it’s the “natural time boundaries”, so I also don’t understand why two items are kept because of “yearly snapshot”.

All calendar related options (--keep-{hourly,daily,...}) work on natural time boundaries and not relative to when you run forget. Weeks are Monday 00:00 to Sunday 23:59, days 00:00 to 23:59, hours :00 to :59, etc. They also only count hours/days/weeks/etc which have one or more snapshots. A value of -1 will be interpreted as “forever”, i.e. “keep all”.

Looking into the code would tell how it’s actually computed.

After some research, I think that the reason is the feature from restic forget: Keep also oldest snapshot when there are not enough backups to keep · Issue #3624 · restic/restic · GitHub which was added in version 0.16.

The code has this line internal/restic/snapshot_policy.go:262 with a comment:

// also keep the oldest snapshot if the bucket has some counts left. This maximizes the
// the history length kept while some counts are left.
if val != b.Last || nr == len(list)-1 {

I could not find any hint in the documentation, though.

1 Like

I think this is related to the fact that there are not enough yearly snapshots to fulfill your request (keep 9 yearly snapshots). Hence the oldest snapshot is also chosen as “yearly” one. The same would apply to monthly etc.

IIRC the behavior was different (and the way you expected it) some months ago, but there was a feature request to add this functionality.

EDIT: Just saw you also found this out…

1 Like

In case you haven’t: If the docs are missing something, please raise an issue or open a PR to fix it :slight_smile:
Since you already checked out the code, I thought I’d at least ask you :wink:

Thanks

Here is what I would add to the documentation: Add a note that the oldest snapshot may be kept additionally by joram-berger · Pull Request #1 · joram-berger/restic · GitHub It looks like this is a pull request in my fork not in the restic repo…

I have no time to push it through any review process. So if you want, please pick it up and merge it.

1 Like

@noeck Thanks! I’ve created Add a note that the oldest snapshot may be kept additionally by MichaelEischer · Pull Request #4600 · restic/restic · GitHub for it.

1 Like