How to Use Btrfs Snapshots on the System Disk (Roll Back a Bad Update in One Command)

Btrfs on the system SSD: a snapshot before every apt run, a rollback from the GRUB menu when an update goes wrong. No extra RAM, no ZFS.

ZFS (97) is the right thing for the data drives, but it's awkward as the root filesystem on Ubuntu and wants memory. Btrfs is built into the kernel, happy on a 2 GB box, and does the thing you most want on a system disk: a snapshot before every update, and a rollback — from the GRUB menu if need be — when a kernel or Docker release breaks something (75, 63). With Snapper it's automatic.

Quick reference

TaskCommand
Install Ubuntu on Btrfsinstaller → custom storage → root as btrfs (creates @ and @home)
Snapper for rootsudo snapper -c root create-config /
Snapshot before/after aptautomatic with snapper + the apt-btrfs-snapshot hook or Snapper's apt plugin
Listsudo snapper -c root list
Undo a change to one filesudo snapper -c root undochange 12..13 /etc/nginx/nginx.conf
Roll the whole root backsudo snapper -c root rollback 12 then reboot
Boot into a snapshotgrub-btrfs adds them to the GRUB menu
Send to another disk`btrfs send -p old newbtrfs receive /mnt/backup/`

1. Install on Btrfs

On a fresh install (1), Custom storage layout: the root partition formatted as btrfs, mounted at /. Ubuntu's installer creates two subvolumes — @ (root) and @home — which is what makes rollbacks clean: you snapshot and replace @ without touching @home. /boot/efi stays FAT; /boot can live inside @.

Already installed on ext4? Converting in place is possible (btrfs-convert) but a reinstall with restore (74, 140) is less risky. Or apply this to a new server.

Check: sudo btrfs subvolume list /.

2. Mount options worth having

In /etc/fstab, the root line:

UUID=… / btrfs defaults,subvol=@,compress=zstd:1,noatime,discard=async 0 0

zstd:1 compression is free space at no measurable cost; discard=async for an SSD. sudo mount -o remount / and sudo btrfs filesystem defrag -r -czstd / once to compress what's there.

3. Snapper

sudo apt install snapper -y
sudo snapper -c root create-config /
sudo snapper -c home create-config /home
sudo snapper -c root list

Snapper makes a .snapshots subvolume and a timeline: hourly snapshots, thinned to daily/weekly/monthly (/etc/snapper/configs/root — set TIMELINE_LIMIT_HOURLY="12", NUMBER_LIMIT="20"). For the apt hook on Ubuntu:

sudo apt install apt-btrfs-snapshot -y

(or Snapper's own snapper-apt plugin where packaged) — every apt install/upgrade gets a pre and post snapshot, so "what did that update change?" is snapper status.

sudo snapper -c root create -d "before docker upgrade"
sudo apt upgrade -y
sudo snapper -c root list

4. Undo

One file:

sudo snapper -c root diff 12..13 /etc/ssh/sshd_config
sudo snapper -c root undochange 12..13 /etc/ssh/sshd_config

The whole root, after a bad update:

sudo snapper -c root rollback 12
sudo reboot

Snapper makes the old snapshot the new default @ and keeps the broken state as a snapshot too. /home is a separate subvolume, so nothing you wrote today is lost. Docker's /var/lib/docker is inside @ — put it on its own subvolume (@docker, mounted at /var/lib/docker, excluded from root snapshots) or your container images roll back with the OS, which is usually fine but slow to re-pull.

5. Roll back from GRUB when it won't boot

sudo apt install grub-btrfs -y
sudo systemctl enable --now grub-btrfsd
sudo update-grub

The GRUB menu gains a Snapshots entry listing every Snapper snapshot. A kernel update that panics (75, case 3): pick yesterday's snapshot, boot read-only into it, then snapper rollback from there. No live USB.

6. Send snapshots elsewhere

A Btrfs snapshot can be streamed to another Btrfs disk — the system equivalent of ZFS send:

sudo btrfs send /.snapshots/13/snapshot | sudo btrfs receive /mnt/backup/root-snaps/
sudo btrfs send -p /.snapshots/13/snapshot /.snapshots/14/snapshot | sudo btrfs receive /mnt/backup/root-snaps/

The -p form sends only the difference. btrbk automates this with retention. Together with restic for the data (55), the whole machine is recoverable to the hour.

Btrfs for data drives?

It does mirrors (-d raid1 -m raid1) with checksums and self-healing like ZFS, in the kernel, with less RAM. Avoid RAID5/6 on Btrfs (still not safe). Many home servers run Btrfs root + ZFS data, or Btrfs everywhere on small boxes.

Troubleshooting

Disk fills though df says space. Old snapshots hold deleted data. sudo snapper -c root cleanup number and lower the limits; sudo btrfs filesystem usage / shows the truth.

"No space left" during balance/snapshot. Metadata exhausted: sudo btrfs balance start -musage=50 /.

Rollback didn't take. The default subvolume wasn't changed (btrfs subvolume get-default /); Snapper's rollback needs the @-style layout.

Scrub, like ZFS. sudo btrfs scrub start / monthly; scrub status for errors.

Wrapping up

Ubuntu on Btrfs with @ and @home, Snapper with the apt hook, grub-btrfs for the menu, btrfs send to the backup disk. A broken update becomes a reboot into yesterday, and the system disk gets the undo button the data drives already had.

Call us