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.
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 /.snapshotsand re-runcreate-config. - Snapshots filling the disk: Run
sudo snapper -c root listto identify old ones, then delete withsudo snapper -c root delete 10-20. TightenNUMBER_LIMITin the config. - GRUB snapshot entries not appearing: Confirm
grub-btrfsis installed, that your snapshots are under/.snapshots, and re-rungrub-mkconfig. Checkjournalctl -u grub-btrfsdfor 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 /mntthen set it:sudo btrfs subvolume set-default <ID> /mnt. - Permission errors running snapper as user: Add your user to the snapper config's
ALLOW_USERSfield in/etc/snapper/configs/root, then runsudo snapper -c root set-config ALLOW_USERS=$USER.
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
Back Up Linux with Borg or restic
Set up encrypted, deduplicated backups with BorgBackup or restic: local and remote repos, retention pruning, restoring files, and systemd timer scheduling.
How to Check Disk Health with SMART
Learn to use smartctl to read SMART attributes, run drive self-tests, and identify early warning signs of HDD and SSD failure before data loss occurs.
Debug systemd Units that Won't Start
Learn a repeatable workflow to debug systemd services that won't start: status output, journalctl, systemd-analyze verify, and safe override.conf patches.
Linux Server Disaster Recovery Checklist
A practical Linux server disaster recovery checklist: what to back up, RTO/RPO planning, immutable off-site copies, automated restore drills, and verification.