All backup space is finite, so restic allows removing old snapshots.
This can be done either manually (by specifying a snapshot ID to remove)
or by using a policy that describes which snapshots to forget. For all
remove operations, two commands need to be called in sequence:
forget to remove a snapshot and prune to actually remove the
data that was referenced by the snapshot from the repository. This can
be automated with the --prune option of the forget command,
which runs prune automatically if snapshots have been removed.
Pruning snapshots can be a time-consuming process, depending on the
amount of snapshots and data to process. During a prune operation, the
repository is locked and backups cannot be completed. Please plan your
pruning so that there’s time to complete it and it doesn’t interfere with
regular backup runs.
Removing snapshots according to a policy
Removing snapshots manually is tedious and error-prone, therefore restic
allows specifying which snapshots should be removed automatically
according to a policy. You can specify how many hourly, daily, weekly,
monthly and yearly snapshots to keep, any other snapshots are removed.
The most important command-line parameter here is --dry-run which
instructs restic to not remove anything but print which snapshots would
be removed.
When forget is run with a policy, restic loads the list of all
snapshots, then groups these by host name and list of directories. The grouping
options can be set with --group-by, to only group snapshots by paths and
tags use --group-by paths,tags. The policy is then applied to each group of
snapshots separately. This is a safety feature.
The forget command accepts the following parameters:
--keep-last n never delete the n last (most recent) snapshots
--keep-hourly n for the last n hours in which a snapshot was
made, keep only the last snapshot for each hour.
--keep-daily n for the last n days which have one or more
snapshots, only keep the last one for that day.
--keep-weekly n for the last n weeks which have one or more
snapshots, only keep the last one for that week.
--keep-monthly n for the last n months which have one or more
snapshots, only keep the last one for that month.
--keep-yearly n for the last n years which have one or more
snapshots, only keep the last one for that year.
--keep-tag keep all snapshots which have all tags specified by
this option (can be specified multiple times).
--keep-within duration keep all snapshots which have been made within
the duration of the latest snapshot. duration needs to be a number of
years, months, days, and hours, e.g. 2y5m7d3h will keep all snapshots
made in the two years, five months, seven days, and three hours before the
latest snapshot.
--keep-within-hourly duration keep all hourly snapshots made within
specified duration of the latest snapshot. The duration is specified in
the same way as for --keep-within and the method for determining
hourly snapshots is the same as for --keep-hourly.
--keep-within-daily duration keep all daily snapshots made within
specified duration of the latest snapshot.
--keep-within-weekly duration keep all weekly snapshots made within
specified duration of the latest snapshot.
--keep-within-monthly duration keep all monthly snapshots made within
specified duration of the latest snapshot.
--keep-within-yearly duration keep all yearly snapshots made within
specified duration of the latest snapshot.
Note
All calendar related --keep-* options work on the natural time
boundaries and not relative to when you run the forget command. Weeks
are Monday 00:00 -> Sunday 23:59, days 00:00 to 23:59, hours :00 to :59, etc.
Note
Specifying --keep-tag '' will match untagged snapshots only.
Multiple policies will be ORed together so as to be as inclusive as possible
for keeping snapshots.
Additionally, you can restrict removing snapshots to those which have a
particular hostname with the --host parameter, or tags with the
--tag option. When multiple tags are specified, only the snapshots
which have all the tags are considered. For example, the following command
removes all but the latest snapshot of all snapshots that have the tag foo:
$ restic forget --tag foo --keep-last 1
This command removes all but the last snapshot of all snapshots that have
either the foo or bar tag set:
$ restic forget --tag foo --tag bar --keep-last 1
To only keep the last snapshot of all snapshots with both the tag foo and
bar set use:
$ restic forget --tag foo,bar --keep-last 1
To ensure only untagged snapshots are considered, specify the empty string ‘’ as
the tag.
$ restic forget --tag '' --keep-last 1
All the --keep-* options above only count
hours/days/weeks/months/years which have a snapshot, so those without a
snapshot are ignored.
For safety reasons, restic refuses to act on an “empty” policy. For example,
if one were to specify --keep-last 0 to forget all snapshots in the
repository, restic will respond that no snapshots will be removed. To delete
all snapshots, use --keep-last 1 and then finally remove the last
snapshot ID manually (by passing the ID to forget).
All snapshots are evaluated against all matching --keep-* counts. A
single snapshot on 2017-09-30 (Sat) will count as a daily, weekly and monthly.
Let’s explain this with an example: Suppose you have only made a backup
on each Sunday for 12 weeks:
$ restic snapshots
repository f00c6e2a opened successfully, password is correct
ID Time Host Tags Paths
---------------------------------------------------------------
0a1f9759 2019-09-01 11:00:00 mopped /home/user/work
46cfe4d5 2019-09-08 11:00:00 mopped /home/user/work
f6b1f037 2019-09-15 11:00:00 mopped /home/user/work
eb430a5d 2019-09-22 11:00:00 mopped /home/user/work
8cf1cb9a 2019-09-29 11:00:00 mopped /home/user/work
5d33b116 2019-10-06 11:00:00 mopped /home/user/work
b9553125 2019-10-13 11:00:00 mopped /home/user/work
e1a7b58b 2019-10-20 11:00:00 mopped /home/user/work
8f8018c0 2019-10-27 11:00:00 mopped /home/user/work
59403279 2019-11-03 11:00:00 mopped /home/user/work
dfee9fb4 2019-11-10 11:00:00 mopped /home/user/work
e1ae2f40 2019-11-17 11:00:00 mopped /home/user/work
---------------------------------------------------------------
12 snapshots
Then forget --keep-daily 4 will keep the last four snapshots for the last
four Sundays, but remove the rest:
$ restic forget --keep-daily 4 --dry-run
repository f00c6e2a opened successfully, password is correct
Applying Policy: keep the last 4 daily snapshots
keep 4 snapshots:
ID Time Host Tags Reasons Paths
-------------------------------------------------------------------------------
8f8018c0 2019-10-27 11:00:00 mopped daily snapshot /home/user/work
59403279 2019-11-03 11:00:00 mopped daily snapshot /home/user/work
dfee9fb4 2019-11-10 11:00:00 mopped daily snapshot /home/user/work
e1ae2f40 2019-11-17 11:00:00 mopped daily snapshot /home/user/work
-------------------------------------------------------------------------------
4 snapshots
remove 8 snapshots:
ID Time Host Tags Paths
---------------------------------------------------------------
0a1f9759 2019-09-01 11:00:00 mopped /home/user/work
46cfe4d5 2019-09-08 11:00:00 mopped /home/user/work
f6b1f037 2019-09-15 11:00:00 mopped /home/user/work
eb430a5d 2019-09-22 11:00:00 mopped /home/user/work
8cf1cb9a 2019-09-29 11:00:00 mopped /home/user/work
5d33b116 2019-10-06 11:00:00 mopped /home/user/work
b9553125 2019-10-13 11:00:00 mopped /home/user/work
e1a7b58b 2019-10-20 11:00:00 mopped /home/user/work
---------------------------------------------------------------
8 snapshots
The result of the forget --keep-daily operation does not depend on when it
is run, it will only count the days for which a snapshot exists. This is a
safety feature: it prevents restic from removing snapshots when no new ones are
created. Otherwise, running forget --keep-daily 4 on a Friday (without any
snapshot Monday to Thursday) would remove all snapshots!
Another example: Suppose you make daily backups for 100 years. Then
forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 75
will keep the most recent 7 daily snapshots, then 4 (remember, 7 dailies
already include a week!) last-day-of-the-weeks and 11 or 12
last-day-of-the-months (11 or 12 depends if the 5 weeklies cross a month).
And finally 75 last-day-of-the-year snapshots. All other snapshots are
removed.
You might want to maintain the same policy as for the example above, but have
irregular backups. For example, the 7 snapshots specified with --keep-daily 7
might be spread over a longer period. If what you want is to keep daily snapshots
for a week, weekly for a month, monthly for a year and yearly for 75 years, you
could specify:
forget --keep-daily-within 7d --keep-weekly-within 1m --keep-monthly-within 1y
--keep-yearly-within 75y
(Note that 1w is not a recognized duration, so you will have to specify
7d instead)