$linuxjunkies
>

Snapshot Backups with Btrfs and Snapper

Set up Btrfs subvolumes, configure Snapper for automated snapshots, integrate with GRUB for bootable recovery points, and perform full system rollbacks.

IntermediateUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • Root filesystem already formatted as Btrfs with @ and @home subvolumes
  • GRUB bootloader installed (not systemd-boot, for grub-btrfs integration)
  • sudo or root access on the target system
  • At least 10 GB of free space on the Btrfs volume to accommodate initial snapshots

Btrfs snapshots give you near-instant, space-efficient backups of your filesystem state. Combined with Snapper, you get automated snapshot policies, diff tools, and—when paired with grub-btrfs—the ability to boot directly into a previous snapshot and roll back a broken system. This guide walks through setting up a production-ready snapshot workflow from subvolume layout through verified rollback.

Understanding the Subvolume Layout

Snapper requires that the directories you want to snapshot live on dedicated Btrfs subvolumes—not on the top-level Btrfs volume itself. A flat layout like @ for root and @home for home is the standard convention used by openSUSE, Fedora, and most Btrfs-first distributions.

If you installed with a distribution that already set this up (Fedora Workstation, openSUSE Tumbleweed, EndeavourOS), you likely already have it. Check your layout:

sudo btrfs subvolume list /

Realistic output looks like:

# ID 256 gen 1234 top level 5 path @
# ID 257 gen 1234 top level 5 path @home
# ID 258 gen 1100 top level 5 path @snapshots

If your root filesystem is the raw top-level Btrfs volume (ID 5), you need to migrate your data into subvolumes before Snapper will work correctly. That migration is outside this guide's scope, but btrfs-convert workflows are well documented upstream.

Your /etc/fstab entries should mount subvolumes explicitly with subvol=@ options, not by subvolume ID, so snapshots don't accidentally become your active root.

Installing Snapper

Debian and Ubuntu

sudo apt install snapper snapper-gui btrfs-progs inotify-tools

Fedora

sudo dnf install snapper python3-snapper

Arch Linux

sudo pacman -S snapper snap-pac

snap-pac is an Arch-specific pacman hook that triggers pre/post snapshots automatically around every package operation—install it.

Creating Snapper Configurations

Each mount point you want to snapshot gets its own Snapper config. Create configs for root and home separately.

sudo snapper -c root create-config /
sudo snapper -c home create-config /home

This creates configuration files in /etc/snapper/configs/ and a hidden .snapshots subvolume at the root of each managed path. Verify:

sudo snapper list-configs

Tuning the Configuration

Edit /etc/snapper/configs/root to set retention limits that match your disk size. Key parameters:

sudo nano /etc/snapper/configs/root

Recommended values for a typical desktop or workstation:

TIMELINE_CREATE="yes"
TIMELINE_CLEANUP="yes"
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="5"
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_WEEKLY="4"
TIMELINE_LIMIT_MONTHLY="6"
TIMELINE_LIMIT_YEARLY="2"
NUMBER_CLEANUP="yes"
NUMBER_LIMIT="50"
NUMBER_LIMIT_IMPORTANT="10"

Tighten TIMELINE_LIMIT_HOURLY and NUMBER_LIMIT on small drives. Snapshots consume space proportional to changes made since the snapshot—an idle system uses almost nothing extra.

Enabling Automated Snapshots

Snapper ships systemd timer units. Enable them:

sudo systemctl enable --now snapper-timeline.timer
sudo systemctl enable --now snapper-cleanup.timer

On Debian/Ubuntu, also enable the boot-time snapshot service if available:

sudo systemctl enable --now snapper-boot.timer

Confirm the timers are scheduled:

systemctl list-timers | grep snapper

Taking Manual and Pre/Post Snapshots

Timeline snapshots are automatic, but you should take explicit snapshots before risky changes. Snapper's pre/post pairs let you diff exactly what changed during an operation.

# Take a pre-snapshot and record the number printed
sudo snapper -c root create --type pre --cleanup-algorithm number --print-number --description "before kernel update"
# 42
# Perform your risky operation, then take the post snapshot
sudo snapper -c root create --type post --pre-number 42 --cleanup-algorithm number --description "after kernel update"

List all snapshots at any time:

sudo snapper -c root list

Diff files changed between two snapshots:

sudo snapper -c root diff 42..43

Restore a single file from a snapshot without rolling back the whole system:

sudo cp /.snapshots/42/snapshot/etc/ssh/sshd_config /etc/ssh/sshd_config

GRUB Integration for Bootable Snapshots

The grub-btrfs tool scans your Btrfs snapshots and adds them as GRUB boot entries, so you can boot a read-only snapshot directly from the menu to test or recover.

Install grub-btrfs

On Debian/Ubuntu:

sudo apt install grub-btrfs

On Fedora:

sudo dnf install grub-btrfs

On Arch:

sudo pacman -S grub-btrfs

Regenerate GRUB Config

sudo grub-mkconfig -o /boot/grub/grub.cfg

On Fedora/RHEL systems using /boot/grub2:

sudo grub2-mkconfig -o /boot/grub2/grub.cfg

Enable the grub-btrfsd daemon to watch for new snapshots and regenerate GRUB automatically:

sudo systemctl enable --now grub-btrfsd

Next time you boot, a Arch Linux snapshots (or equivalent) submenu appears in GRUB listing all your Snapper snapshots by description and date.

Important: Snapshots booted from GRUB are read-only by default. Use them for inspection and recovery, not for working in directly.

Rolling Back the Root Subvolume

A full rollback replaces your active root subvolume with a snapshot. This is the recovery path when an update or configuration change breaks your system.

Method 1: Snapper Rollback (openSUSE / systemd-boot systems)

sudo snapper rollback 42

On openSUSE this is fully supported and sets the default subvolume to the snapshot. Reboot and the rolled-back system is active.

Method 2: Manual Rollback (Arch, Debian, Fedora)

Boot from a live USB or boot the target snapshot read-only from GRUB. Mount the Btrfs top-level volume:

sudo mount -o subvolid=5 /dev/sdXY /mnt

Rename the broken root subvolume and replace it with the snapshot:

sudo mv /mnt/@ /mnt/@_broken_$(date +%F)
sudo btrfs subvolume snapshot /mnt/@snapshots/42/snapshot /mnt/@

Unmount and reboot:

sudo umount /mnt
sudo reboot

After confirming the system is healthy, delete the broken subvolume:

sudo btrfs subvolume delete /mnt/@_broken_2025-06-01

Verification

After setup, confirm everything is running correctly:

# Check timers are active
systemctl list-timers snapper-timeline.timer snapper-cleanup.timer

# Trigger a manual timeline snapshot to verify config works
sudo snapper -c root create --description "test snapshot"

# List snapshots
sudo snapper -c root list

# Check disk usage across snapshots
sudo btrfs filesystem du -s /.snapshots/*

Troubleshooting

  • "/.snapshots already exists and is not a subvolume": Snapper found a plain directory instead of a subvolume. Remove it with sudo rmdir /.snapshots and re-run create-config.
  • Snapshots filling the disk: Run sudo snapper -c root list to identify old ones, then delete with sudo snapper -c root delete 10-20. Tighten NUMBER_LIMIT in the config.
  • GRUB snapshot entries not appearing: Confirm grub-btrfs is installed, that your snapshots are under /.snapshots, and re-run grub-mkconfig. Check journalctl -u grub-btrfsd for errors.
  • Rollback boots into the same broken system: The default Btrfs subvolume wasn't changed. Boot a live environment, mount subvolid=5, and verify which subvolume is set as default with sudo btrfs subvolume get-default /mnt then set it: sudo btrfs subvolume set-default <ID> /mnt.
  • Permission errors running snapper as user: Add your user to the snapper config's ALLOW_USERS field in /etc/snapper/configs/root, then run sudo snapper -c root set-config ALLOW_USERS=$USER.
tested on:Ubuntu 24.04Fedora 40Arch 2025.05.01openSUSE Tumbleweed 20250520

Frequently asked questions

How much extra disk space do Btrfs snapshots use?
Snapshots use copy-on-write, so a fresh snapshot uses almost no space. Space is consumed only as the live filesystem diverges from the snapshot—heavy package updates or large file writes accumulate the most overhead. Check usage with 'btrfs filesystem du -s /.snapshots/*'.
Can I use Snapper if I didn't install with a subvolume layout?
Not without first migrating your data into subvolumes. You need to create @ and @home subvolumes, copy data into them, update fstab to mount them explicitly, and update the initramfs before Snapper will work correctly.
Are snapshots a replacement for offsite backups?
No. Snapshots live on the same disk as your data—a drive failure destroys both. Use Snapper for fast rollback of software changes, and pair it with a real backup tool like borgbackup or rsync to an external or remote destination.
Why does booting a snapshot from GRUB mount it read-only?
Btrfs snapshots are read-only by default to preserve their integrity as recovery points. If you need a writable copy to make repairs, take a new writable snapshot from it with 'btrfs subvolume snapshot /.snapshots/42/snapshot /mnt/repair'.
Will Snapper snapshot /home and / together atomically?
No. Each Snapper config snapshots its target independently. There is a brief window between the two snapshots. For most desktop and server use cases this is acceptable; database-consistent backups require application-level quiescing regardless of the snapshot tool.

Related guides