May 27, 2025
OpenZFS is a first class citizen on FreeBSD for a number of years now. Right from the installer, users can install a complete root-on-ZFS system. FreeBSD will create the necessary datasets for the base operating system, including one for /usr
, /var
, and /home
.
If disaster strikes and files get lost, ZFS can restore data by rolling back to a previous snapshot – given that one exists for that particular dataset. The missing piece is a functionality to take automatic snapshots in regular intervals and rotate them. Rotation means that older snapshots get removed based on a certain user-defined policy. This avoids filling the dataset with millions of snapshots over time. While OpenZFS provides all the basic commands to take and remove snapshots, the user is responsible for managing their own snapshot agenda. This means how often a snapshot should occur on each dataset and what the rules for their removal are.
Over the years, programmers created separate solutions that offered this automatic snapshot functionality. Available as third-party software via the FreeBSD ports collection or precompiled packages, many of them are quick and easy to set up. This article takes a closer look at sanoid, written by Jim Salter. It offers the user to write their own policy that determines when and how often snapshots should happen. For example, system administrators may chose to snapshot the home
dataset more frequently than the /usr/src
dataset. The former contains critical and frequently changing data, whereas the latter is easily re-created from scratch (unless you’re a developer working on code in there).
Sanoid’s configuration file sanoid.conf
located in the /usr/local/etc
defines the policy. Consider the following example policy:
[template_zroot]
hourly = 36
daily = 14
monthly = 6
autosnap = yes
autoprune = yes
frequent_period = 15
frequently = 2
Here, we instruct sanoid to take and retain 36 hourly snapshots. Once the 37th snapshot is taken, the oldest one is removed. We’re keeping 14 daily snapshots (two weeks) and half a year of monthly snapshots. The snapshots themselves are taken recursively, meaning datasets below the zroot
(in this case) also get snapshots. This is true for the current and any future snapshots that do not exist yet. This ensures that no dataset gets missed by the policy. The autosnap = yes
line tells sanoid to take these snapshots automatically and give them a custom name. With the autoprune
option activated, sanoid will remove older snapshots automatically. The frequent_period
setting defines how many snapshots to take under an hour. In this case, sanoid takes a new snapshot every 15 minutes (4 per hour). Similarly, the frequently
parameter defines how many snapshots under the hour to keep when pruning happens. Here we keep two snapshots of each hour.
When datasets need a different snapshot frequency, define a separate policy for them. The following line separates policies (below) from the datasets they should apply to (above).
#############################
# templates below this line #
#############################
We have created an Ansible playbook that sets up sanoid on a FreeBSD system and configures the above policy. Sanoid executes from /etc/crontab
and the playbook takes an initial snapshot as the last step of the playbook. With this, you will always have a snapshot available to retrieve an older state of your datasets. Tweak the numbers in the policy to have fewer or even more snapshots, based on how frequent the data changes and how much pool space is available.
Take a look at syncoid (part of the sanoid package) by the same author to transfer these snapshots via zfs send
to a separate system for backup purposes.
We’re dropping new posts — and videos — for technical topics on a regular basis. So make sure you’re subscribed to the YouTube channel and following this feed in your favourite RSS reader. There’s also the newsletter, if you’d like to receive updates by email.
We’d like this content to be interactive — so what would you like to see us cover? What FreeBSD related topics puzzling you could we help with? Feel free to get in touch with your ideas.
Contributed by Benedict Reuschling