Get It Done in 5 Minutes — No Complex Setup Required
If your machine is running Fedora 33 or later, the root filesystem is already Btrfs by default. That means you can create a snapshot right now without installing anything extra.
Quickly check if you’re already using Btrfs:
df -T /
# The Type column should show "btrfs"
Create a read-only snapshot of the root subvolume:
# Create the snapshots directory (only needs to be done once)
sudo mkdir -p /.snapshots
# Create a snapshot named by date and time
sudo btrfs subvolume snapshot -r / /.snapshots/root-$(date +%Y%m%d-%H%M)
Verify the snapshot was created:
sudo btrfs subvolume list / | grep snapshots
Done — you now have a full backup of your system state. If you need to recover a file later, just mount this snapshot and copy it out.
Why You Need Snapshots — A Real-World Story
I’ve been using Fedora as my primary development machine for two years and I really appreciate its fast package update cycle. But precisely because Fedora moves fast, occasionally a package upgrade breaks something that was working fine. The most common culprits are NVIDIA drivers or a Python library with an ABI change.
Before discovering snapshots, every incident meant hours of debugging. Now it’s much simpler: take a snapshot before running dnf upgrade, and if something breaks, roll back in a few minutes — no harm done.
How Do Snapshots Work?
A Btrfs snapshot doesn’t copy all your data — it uses a Copy-on-Write (CoW) mechanism. When you create a snapshot, Btrfs simply records the current state by referencing existing data blocks. Only when you modify a file afterward does Btrfs actually copy the old block to a new location and write the new data there.
Thanks to this mechanism, snapshots complete in under a second and initially consume almost no additional space. Storage usage only grows gradually as the system changes over time.
Compared to Traditional Backups
- Creation speed: Btrfs snapshots complete in under a second. An rsync backup takes tens of minutes.
- Initial storage size: A snapshot takes nearly 0 bytes when first created. A copy-based backup doubles your data immediately.
- Limitations: Snapshots only work within the same Btrfs filesystem. Backing up to an external drive still requires additional tools.
Using Snapper for Automation — Set It Up Once, It Runs Forever
Creating snapshots manually is fine for your first try, but in practice you’ll forget to do it before running a risky command. Snapper solves that problem — it manages snapshots and, most importantly, integrates with DNF to automatically capture the system state before and after every update.
Installing Snapper and the DNF Plugin
sudo dnf install snapper python3-dnf-plugin-snapper
Create a Snapper configuration for the root subvolume:
sudo snapper -c root create-config /
View the default configuration that was just created:
sudo snapper -c root get-config
Creating Snapshots Manually with Snapper
# Create a snapshot with a description
sudo snapper -c root create --description "Before testing Nginx config"
# List all snapshots
sudo snapper -c root list
The output will look like this:
# | Type | Pre # | Date | User | Description
----+--------+-------+---------------------------+------+-------------------------
0 | single | | | root | current
1 | single | | 2025-03-15 09:30:12 +0900 | root | Before testing Nginx config
Automatic Snapshots When Running dnf
After installing python3-dnf-plugin-snapper, the plugin will automatically create a “pre” and “post” snapshot pair every time you run dnf. No additional configuration needed:
sudo dnf upgrade
# Snapper automatically creates a "pre" snapshot before the upgrade begins
# And a "post" snapshot after it completes
Check the results after the upgrade completes:
sudo snapper -c root list
# You'll see the pre/post snapshot pair with types "pre" and "post"
Comparing Changes Between Two Snapshots
The feature I use most is checking which files changed after an upgrade — especially useful when you need to know which config files were overwritten:
# Compare snapshot 3 (pre) and snapshot 4 (post)
sudo snapper -c root status 3..4
# View detailed diff of a specific file
sudo snapper -c root diff 3..4 /etc/nginx/nginx.conf
Rolling Back When Something Goes Wrong
Rolling Back a Specific File — Fastest Fix for Minor Issues
Accidentally deleted a file or broke a config after editing it:
# Restore a specific file from snapshot 1 to the current state (0)
sudo snapper -c root undochange 1..0 /etc/fstab
# Or manually mount the snapshot and copy the file
sudo mount -o ro,subvol=/.snapshots/1/snapshot /dev/sda3 /mnt
cp /mnt/etc/fstab /etc/fstab
sudo umount /mnt
Full System Rollback via GRUB
For more serious situations — the new kernel won’t boot, or an upgrade broke the desktop environment. Install grub-btrfs so GRUB shows a menu for booting into a snapshot:
sudo dnf install grub-btrfs
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Reboot, and GRUB will have a new “Fedora snapshots” entry to boot into an old snapshot. Once you’ve successfully booted into the snapshot you want to keep:
sudo snapper rollback
sudo reboot
Note: snapper rollback works best when the subvolume layout follows the Snapper standard. With Fedora’s default layout (subvolumes @ and @home), you should check Snapper’s documentation to verify compatibility before using this in a production environment.
Practical Tips for Sustainable Snapshot Usage
Create an Alias for the Snapshot-Before Habit
Add to ~/.bashrc to quickly take a snapshot before any risky operation:
# Add to ~/.bashrc
alias snap-now='sudo snapper -c root create --description "Manual: $(date +%Y%m%d-%H%M)"'
# Reload bashrc
source ~/.bashrc
# Usage: snap-now && sudo dnf upgrade
Managing Disk Space — Don’t Let Snapshots Fill Your Drive
After a few weeks of regular updates, /.snapshots can consume 5–20 GB depending on how much the system changes. Configure Snapper’s timeline cleanup to keep a reasonable number of snapshots:
sudo snapper -c root set-config \
TIMELINE_CREATE=yes \
TIMELINE_LIMIT_HOURLY=5 \
TIMELINE_LIMIT_DAILY=7 \
TIMELINE_LIMIT_WEEKLY=2 \
TIMELINE_LIMIT_MONTHLY=1 \
TIMELINE_LIMIT_YEARLY=0
Delete old snapshots you no longer need:
# Delete snapshot number 5
sudo snapper -c root delete 5
# Delete multiple snapshots at once
sudo snapper -c root delete 3-8
# Check how much space snapshots are using
sudo btrfs filesystem du -s /.snapshots/*
Backing Up Snapshots to an External Drive with btrfs send
Snapshots on the same drive only protect you from software failures, not hardware failures. For true off-device backup, use btrfs send to send snapshots to an external drive:
# Assume the external drive is mounted at /backup (must be a Btrfs filesystem)
# Send a full snapshot
sudo btrfs send /.snapshots/1/snapshot | sudo btrfs receive /backup/
# Send incremental — only the changes since the previous snapshot, extremely fast
sudo btrfs send -p /.snapshots/1/snapshot /.snapshots/2/snapshot | \
sudo btrfs receive /backup/
Incremental backups only transfer the data that changed between two snapshots — instead of copying tens of gigabytes, you’re transferring just a few hundred megabytes for each daily backup.
After using this workflow for a while, I barely feel any anxiety before running dnf upgrade. Snapshots take under a second, rollbacks take a few minutes — a trade-off that’s absolutely worth it compared to hours of debugging when something goes wrong.

