Configure Fedora with full root level snapshot support
A guide walking you through how to configure your Fedora installation to get full root snapshot and rollback support.

Whether you've been introduced to Fedora by watching recent YouTube videos on it, have known about it for some time and it's finally time to give it a real try, or you've used it in the past and are eager to get back to all that it offers, this guide might be helpful to you if you're looking to set up BTRFS snapshots right away.
Fedora is a fantastic choice with a lot going on for itself. It's out of the box experience is wonderful, with most everything just working. This is a really nice choice for people who want their machine to work and don't want to spend potentially large amounts of time tinkering and bug fixing.
With that said, Fedora's out of the box BTRFS configuration unfortunately leaves a bit to be desired. This is what this guide sets out to solve.
/boot
partition and potential caveats of restoring to (very) old snapshots with kernel versions no longer present your system, and a change in my personal usage of the setup this guide describes.Snapshots?
If you're less familiar with what snapshots are or how they can be used; they basically allow your system to make a moment-in-time capture of your drive or directory, allowing you to revert back to that state at a later point if needed. It does this without making a copy of everything, so unlike more traditional backup or clone type solutions, this won't actually fill up your drive super quick or take ages to complete.
BTRFS works by what it calls Copy-on-Write (delightfully abbreviated to CoW. Moo!), which means whenever writes occur it doesn't actually overwrite existing data, it instead creates a new modified copy of the data block elsewhere, and updates the metadata to point to that block instead. This is what BTRFS' snapshot functionality uses to allow for these moments in time to be captured very quickly and, at least initially, take up basically no additional space.
Installing Fedora
What we're going to walk through will be compatible with all more recent versions of Fedora. I have tested and used this with Fedora 34, 35, as-well as Fedora 36 – which is in beta at the time of this writing.
This guide assumes you are planning on installing Fedora as the only OS to a drive. If you are planning on dual booting with another OS, please ensure you adjust the necessary steps to accommodate this. It might be useful to follow a guide on that specific subject if needed.
With a Fedora live USB stick created, boot up your system and select the install Fedora option when prompted. After selecting your region/language, you'll be greeted with the following screen.

This might be one of the least intuitive parts of the Fedora installation, but they're apparently working on an updated installer that should remedy this. Regardless, unless you are planning on dual booting, the steps here are fortunately very straight-forward – UX oddities aside.
Click the Installation Destination
option under the System header, in the following screen you'll be able to select which drive you'd like to install Fedora too. If you only have one drive, you might find that it is already selected. You can tell by the white-on-black check mark that appears on the drive.

By default the installer will have also selected the "Automatic" storage configuration option. Unless you need to customize things for a dual-boot setup or so, this is the easiest route to take.
In case your drive already has another OS installed, you should tick the "I would like to make additional space available" checkbox. This will let you remove existing partitions, after which the Fedora installer's "automatic" mode can create the necessary partitions.
Once you're ready, click the "Done" button hidden away in the top-right corner of the installer, and then proceed with the installation by clicking the start installation button.
This will take a little bit, after which your system should automatically reboot and bring you to the account setup, and final, step of the Fedora installation process. Follow these final steps until you are greeted with Fedora's nice and clean desktop.

Configuring BTRFS
With the installation done and your system booted into a nice and fresh Fedora installation, let's actually make the necessary changes to get our root-level snapshots working the way we want it. We'll also install and configure a tool that automatically creates snapshots before and after dnf
upgrades, too.
In case you haven't already, it might be a good idea to update your system right away so everything is fully up-to-date.
For these next few steps we'll mostly be using terminal commands, so let's open up Terminal now.
By default Fedora's installation configures two BTRFS subvolumes; one for your root drive (/
), the other for your home directory (/home
). You can confirm this by running the following command:
❯ sudo btrfs subvolume list / | grep "level 5"
You'll see something like this as the result:
❯ sudo btrfs subvolume list / | grep "level 5"
ID 256 gen 36 top level 5 path home
ID 257 gen 36 top level 5 path root
Installing Snapper
Let's proceed. We'll install a utility called snapper
, along with its dnf
plugin. Run the following command to install both:
❯ sudo dnf install snapper python-dnf-plugin-snapper
With snapper
installed, let's create and configure snapshots for the root partition first. Run teh following command to do this:
❯ sudo snapper -c root create-config /
Creating a root-level .snapshots
subvolume
Creating this configuration also creates a snapshots subvolume. However, this is created as as subvolume directly under the root partition, which we don't want. You can see what I mean by listing out the btrfs subvolumes again. You'll see something like this:
❯ sudo btrfs subvolume list /
ID 256 gen 43 top level 5 path home
ID 257 gen 58 top level 5 path root
ID 258 gen 25 top level 257 path var/lib/machines
ID 259 gen 58 top level 257 path .snapshots
Note the .snapshots
volume with its level of 257
. To correct this, let's delete this automatically created subvolume and create a new one that's at the same level as the root and home subvolumes. First, let's delete the subvolume:
❯ sudo btrfs subvolume delete /.snapshots
Now we can re-create it, but at the right level. As you noticed earlier, the default Fedora installation has two subvolumes. Even though we look at /
as the root volume, in this case it actually exists in a subvolume of its own. The actual root of your drive isn't mounted directly, only the two subvolumes are.
In order for us to create another subvolume at this higher level, we need to temporarily mount the real root drive so we can run the appropriate commands from there.
There's several ways to do this. For this guide we'll use the drive's UUID. This is easily discoverable by listing out the contents of your system's fstab
file, like so:
❯ cat /etc/fstab
The results will look something like this:
UUID=2271c46d-9093-4373-9b9f-4f4bac3f944f / btrfs subvol=root,compress=zstd:1 0 0
UUID=a83793bc-31dc-4d79-b4b9-adadafdde13b /boot ext4 defaults 1 2
UUID=2271c46d-9093-4373-9b9f-4f4bac3f944f /home btrfs subvol=home,compress=zstd:1 0 0
In my example –which is running inside a virtual machine– the main drive's UUID is 2271c46d-9093-4373-9b9f-4f4bac3f944f
, you can see how both the /
and /home
subvolumes reference this same UUID. Take a look at your own system and make note of the primary drive's UUID. We'll need it for the next step.
Let's create a new empty directory where the snapshots will be mounted, as-well as a temporary directory to which we can mount the drive, and then mount the actual drive to it:
❯ sudo mkdir /mnt/btrfs /.snapshots
❯ sudo mount /dev/disk/by-uuid/2271c46d-9093-4373-9b9f-4f4bac3f944f /mnt/btrfs
Substitute the UUID with the one you found.
Now with the actual drive mounted, let's cd into it and create the new root-level snapshot subvolume:
❯ cd /mnt/btrfs
❯ sudo btrfs subvolume create snapshots
Let's confirm that everything looks alright by listing out all subvolumes. The results should look something like this:
❯ sudo btrfs subvolume list / | grep "level 5"
ID 256 gen 129 top level 5 path home
ID 257 gen 132 top level 5 path root
ID 259 gen 132 top level 5 path snapshots
With this done, we can unmount the root drive again, clean up after ourselves, and continue with the final bits of configuration.
❯ cd ~
❯ sudo umount /mnt/btrfs
❯ sudo rmdir /mnt/btrfs
Using your favorite text editor with sudo
permissions, open up /etc/fstab
and let's add the new sub-volume. We do this by adding a new line to this file that references the same UUID we used just before, and references the newly created snapshots
sub-volume.
The easiest way is to just duplicate the line already in your fstab
file for the home
sub-volume and changing the mount path as-well as subvol
value. The end result should look something like this:
UUID=2271c46d-9093-4373-9b9f-4f4bac3f944f / btrfs subvol=root,compress=zstd:1 0 0
UUID=a83793bc-31dc-4d79-b4b9-adadafdde13b /boot ext4 defaults 1 2
UUID=2271c46d-9093-4373-9b9f-4f4bac3f944f /home btrfs subvol=home,compress=zstd:1 0 0
UUID=2271c46d-9093-4373-9b9f-4f4bac3f944f /.snapshots btrfs subvol=snapshots,compress=zstd:1 0 0
Save and close the file. We can now try to auto mount everything to make sure everything is working as it should by running:
❯ sudo systemctl daemon-reload
❯ sudo mount -a
(Optional) Creating additional sub-volumes as desired
While this article only specifically covers how to set up root-level snapshot support, it might be worth considering setting up additional sub-volumes while you're at it.
For example, if you use Docker, creating a sub-volume and mounting it to /var/lib/docker
would prevent root snapshots from filling up with docker volume data and also ensure that if you do roll back your root to a previous state, you don't lose anything related to your docker containers when doing so.
If you'd like to do this, you can effectively follow the same steps listed above, but instead create a sub-volume named something like docker
, and adding a row in your fstab
file that mounts it to the path mentioned above.
If you already have existing running containers and volumes there, you can first temporarily disable Docker, temporarily move all contents of the btrfs
folder elsewhere, then create the sub-volume as described above, and after mounting it move everything from the btrfs
folder you temporarily moved just before back.
Another example might be if you install Steam games on your root drive. You could create a sub-volume specifically for the ~/.local/share/Steam
directory (assuming you are using a system-installed Steam – the path will be different if you use the Flatpak version for example), ensuring that reverting to a previous snapshot of your home directory won't make you lose your already downloaded games.
Updating Grub
By default Fedora configures grub to simply reference the top level as the default subvolume. We need to change this to be able to support root subvolume rollbacks. First, let's check what the current configuration says:
❯ sudo btrfs subvolume get-default /
ID 5 (FS_TREE)
Recall when listing out the BTRFS subvolumes that we could see their respective IDs:
❯ sudo btrfs subvolume list / | grep "level 5"
ID 256 gen 129 top level 5 path home
ID 257 gen 132 top level 5 path root
ID 259 gen 132 top level 5 path snapshots
In my example's case, the root
subvolume has an ID of 257
. Check your system's IDs and once you've found the correct one for your root
subvolume, update the default value with the following command:
❯ sudo btrfs subvolume set-default 257 /
Now when checking again, it should look something like this:
❯ sudo btrfs subvolume get-default /
ID 257 gen 143 top level 5 path root
Next we need to update the Grub configuration to not specifically reference the root
subvolume by name. Fedora comes with a utility called grubby
by default which seems to be the Fedora way of doing this. We want to remove this reference by name so that the default
value we have just configured can do its thing:
❯ sudo grubby --update-kernel=ALL --remove-args="rootflags=subvol=root"
With that done, we should now be ready to enjoy root-level snapshots with the ability to rollback.
Let's reboot now before we do anything else.
/boot
partition (and with it /boot/efi
) are not included in these snapshots, as these are not formatted using BTRFS. I'm sure there would be a way to use pre/post hooks to copy contents from these volumes into and from a backup directory that could then be part of BTRFS snapshots, but that is a bit outside the scope of this guide. This is more involved than I think is worth it, as it would only really serve to allow you to restore (very) old snapshots that run kernel versions that have since been removed.
By default Fedora is set up to keep up to three Kernel versions installed. This can be modified to your liking by changing the
installonly_limit
value in /etc/dnf/dnf.conf
, but keep in mind that by default your /boot
partition is only assigned about 1GB of space.
Now every time you install, update, or remove something through dnf
, snapshots are automatically created before and after these actions. This includes anything you might install/update/remove through the Software Center GUI application – though not when installing flatpaks of course.
Here's an example of what my snapper ls
results look like after installing 0 A.D.:
❯ sudo snapper ls
# | Type | Pre # | Date | User | Cleanup | Description | Userdata
---+--------+-------+---------------------------------+------+---------+--------------------------+---------
0 | single | | | root | | current |
1 | pre | | Mon 18 Apr 2022 01:32:52 PM KST | root | number | /usr/bin/dnf install 0ad |
2 | post | 1 | Mon 18 Apr 2022 01:33:07 PM KST | root | number | /usr/bin/dnf install 0ad |
You'll notice that each snapshot has an ID listed. If you ever need to roll back to a previous state, you can use that ID to pick the state to roll back to. For example, if I want to revert to the state just before installing 0 A.D., I could run the following:
❯ sudo snapper --ambit classic rollback 1
As snapshots are read-only by default, when rolling back snapper actually creates a new read-writeable snapshot based off of the snapshot you specified, and sets that as the new bootable subvolume. You can see this by listing out the snapshots after running the above command. It should look something like this:
❯ sudo snapper ls
# | Type | Pre # | Date | User | Cleanup | Description | Userdata
---+--------+-------+---------------------------------+------+---------+--------------------------+--------------
0 | single | | | root | | current |
1 | pre | | Mon 18 Apr 2022 01:32:52 PM KST | root | number | /usr/bin/dnf install 0ad |
2 | post | 1 | Mon 18 Apr 2022 01:33:07 PM KST | root | number | /usr/bin/dnf install 0ad |
3 | single | | Mon 18 Apr 2022 01:38:52 PM KST | root | number | rollback backup | important=yes
4+ | single | | Mon 18 Apr 2022 01:38:52 PM KST | root | | writable copy of #1 |
Now when you reboot
, your system should be back to exactly what it looked like before installing the tool/module/thingy. I realize that my example of installing 0 A.D. wasn't a very useful use-case example, but you can imagine that this could be invaluable when installing something potentially unstable, or accidentally removing critical system level tools for example.
Adding snapshots for home, too
The way BTRFS snapshots work is that they do not include subvolumes inside other subvolumes when making snapshots, so your /home
directory is not included in snapshots for /
.
This is actually a good thing, as it allows us to configure our home directory snapshots separately and in exactly the way we want. What's more, it allows you to revert your system to an earlier snapshot without losing any files stored in your /home
. Pretty neat, right?
Let's create another snapper config, this time for your home directory:
❯ sudo snapper -c home create-config /home
Let's add your user to the list of allowed users that are able to manage this configuration, so you don't have to use sudo
when interacting with your home snapshots. Here we also enable the SYNC_ACL
option which ensures file permissions are set to match whatever we configure through snapper for this particular configuration:
❯ sudo snapper -c home set-config SYNC_ACL=yes ALLOW_USERS=$USER
With that set, you should now be able to interact with snapper for your home directory without requiring sudo
. Let's try creating a manual snapshot now:
❯ snapper -c home create --description "Hello, snapshot!"
❯ snapper -c home ls
# | Type | Pre # | Date | User | Cleanup | Description | Userdata
---+--------+-------+---------------------------------+------------+---------+------------------+---------
0 | single | | | root | | current |
1 | single | | Mon 18 Apr 2022 02:07:50 PM KST | davejansen | | Hello, snapshot! |
Nice.
Scheduled snapshots
Depending on your personal preferences, you might want to have snapper automatically create scheduled snapshots too. By default a configuration has hourly snapshots set, which we probably don't want for the root volume at least. Let's disable this.
Disabling hourly snapshots for root
Open /etc/snapper/configs/root
with your favorite text editor and sudo
or root privileges, look for the TIMELINE_CREATE
value, and set this to no
, so it'll look like this:
# create hourly snapshots
TIMELINE_CREATE="no"
Save your changes and close the file.
Customizing scheduled home snapshots
For your home directory, keeping hourly snapshots can have some nice benefits, so sticking with this default is probably a good thing. There are several additional settings you can tweak that control the number of hourly, daily, weekly, monthly, and yearly snapshots it wants to preserve. Keep in mind that the higher you set these numbers, the more space will be used by these snapshots over time. Here's one example of what this could look like:
# limits for timeline cleanup
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="12"
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_WEEKLY="2"
TIMELINE_LIMIT_MONTHLY="6"
TIMELINE_LIMIT_YEARLY="1"
Adjust these to your liking and save the file. Snapper will automatically pick up these changes.
Enabling scheduled snapshots and cleanup
In order for snapper to be able to run these scheduled tasks we need to enable the appropriate systemd timers:
❯ sudo systemctl enable --now snapper-timeline.timer
❯ sudo systemctl enable --now snapper-cleanup.timer
If you didn't enable any scheduled snapshots and just want the cleanup to happen automatically, you can enable only the second one.
Closing thoughts
We should now have a nice base Fedora setup with full snapshot and rollback support, even on the root level. While Fedora in general is a very stable experience – I've had absolutely no issues so far, it's such a pleasant experience! – there's always the possibility of a rogue tool or driver or configuration causing a ruckus. Having this extra layer of security is very nice for those kinds of cases.
When a new release of Fedora comes out, it's also nice to be able to upgrade your system and know that if anything breaks and either can't yet be fixed or you just don't have the time/interest to investigate, you're able to roll back to before the upgrade and continue with your working system, leaving that problem for another day.
I ran this exact configuration on both my main machine as-well as my laptop, and it was working great while I was using it. For the past 6 or 8 months or so I have not used this particular setup anymore, as I have personally fully moved over to using Fedora Silverblue on all my systems, where you basically get this out of the box, albeit in a very different way of course.
If you are using Workstation and followed along with this guide, I do hope this has been helpful to you. It know it might look a bit daunting with all these commands you have to run, but my hope is that I've written it out in an easy enough to follow way, with mostly copy/past-able commands.
I know that one day this guide will no longer be necessary as Fedora's longer term plans are to effectively move completely over to a Silverblue-esque immutable file system approach. But for now, at least, you'll be able to enjoy Workstation with root-level snapshots support.
I hope you'll enjoy your Fedora system!
Thank you.