Snapper on openSUSE: undo a bad update or a broken file
Find the snapshot from before the problem, restore one file or the whole system, and keep snapshots from filling the disk.
Part 5 of 10 in openSUSE home server setup. Last updated
In short: zypper creates a pre and post snapshot for every transaction. sudo snapper list shows them, snapper status 41..42 shows what changed, and snapper undochange 41..42 /path restores single files. For a broken system, pick an older read-only snapshot in the boot menu, check that it works, then run sudo snapper rollback and reboot. A rollback covers the root file system only: /home, /var (logs and container storage), /srv and /opt keep their current state, so snapper is not a backup.
How snapshots happen
The root file system is btrfs, and snapper takes copy-on-write snapshots of it into
/.snapshots. The snapper-zypp-plugin package makes zypper take one
snapshot before and one after every install, update or removal. A snapshot costs almost
nothing until files change; after that it holds the old versions.
See what changed
snapper reads root's snapshots, so every command needs root:
sudo snapper list # number, type, date, description
sudo snapper status 41..42 # files changed between pre 41 and post 42
sudo snapper diff 41..42 /etc/ssh/sshd_config
Pre and post snapshots come in pairs; the description says which zypper command made them. In
status output, + means created, - deleted and
c changed content.
Restore one file
An update overwrote a config file you tuned, or you broke one yourself:
sudo snapper undochange 41..42 /etc/ssh/sshd_config # back to how it was in 41
sudo cat /.snapshots/41/snapshot/etc/fstab # or just read the old version
Every snapshot is a normal directory tree under /.snapshots/N/snapshot/, so you
can also copy a file out by hand.
Roll back the whole system
- Reboot. In the boot menu, choose the entry for read-only snapshots and pick the pre snapshot from before the bad update.
- The system boots read-only from that snapshot. Check that the problem is gone.
- Make it permanent and reboot:
sudo snapper rollback # copies the booted snapshot to a new read-write default
sudo reboot snapper rollback does not delete anything: the broken state stays as a snapshot
too, in case you want to look at it later. On Tumbleweed, the next zypper dup
will offer the same update again; wait a snapshot or two if the bug is known, or lock the
guilty package as shown in the zypper updates guide.
What a rollback does not touch
The default layout keeps several directories in their own btrfs subvolumes, outside the root snapshots. A rollback leaves them exactly as they are now:
| Directory | What lives there | Consequence |
|---|---|---|
/home | Your files, rootless podman images and volumes | Container data is not rolled back |
/var | Logs, rootful container storage, databases | Logs survive (good for debugging), data is not rolled back |
/srv, /opt, /usr/local | Data and self-installed software | Not rolled back |
That is deliberate: you want your data to survive a rollback of the operating system. It also means snapper is no backup. For that, see the rsync and tar guide and the backup command builder.
Snapshots and disk space
sudo btrfs filesystem usage / # real free space, unlike df
sudo snapper delete 30-40 # delete a range of old snapshots
sudo grep -E 'NUMBER_LIMIT|TIMELINE_CREATE' /etc/snapper/configs/root
The snapper-cleanup.timer thins out old snapshots using the limits in
/etc/snapper/configs/root. On a small root partition, lower
NUMBER_LIMIT (for example to "2-6") and leave timeline snapshots off;
zypper snapshots are the ones that save you. Confused by df, du and free? The
df, du and free explainer reads their output
for you, and the disk space guide covers the rest.
The limits on a real machine, readable without root. TIMELINE_CREATE="no" means
no hourly timeline snapshots, only zypper's pre and post pairs and your own, and SPACE_LIMIT="0.5" lets snapshots
use at most half the file system:
$ findmnt /.snapshots
TARGET SOURCE FSTYPE OPTIONS
/.snapshots /dev/mapper/system-root[/@/.snapshots] btrfs rw,relatime,ssd,discard=async,space_cache=v2,subvolid=265,subvol=/@/.snapshots
$ grep -E '^(NUMBER_LIMIT|NUMBER_LIMIT_IMPORTANT|TIMELINE_CREATE|SPACE_LIMIT)=' /etc/snapper/configs/root
SPACE_LIMIT="0.5"
NUMBER_LIMIT="2-10"
NUMBER_LIMIT_IMPORTANT="4-10"
TIMELINE_CREATE="no" Real output on openSUSE Tumbleweed, 2026-09-28; user and host names and addresses redacted.
And the timer that enforces them, once an hour and ten minutes after boot:
$ systemctl cat snapper-cleanup.timer
# /usr/lib/systemd/system/snapper-cleanup.timer
[Unit]
Description=Hourly Cleanup of Snapper Snapshots
Documentation=man:snapper(8) man:snapper-configs(5)
[Timer]
OnBootSec=10m
OnUnitActiveSec=1h
[Install]
WantedBy=timers.target Real output on openSUSE Tumbleweed, 2026-09-28; user and host names and addresses redacted.
Frequently asked questions
Does snapper replace backups?
No. Snapshots live on the same disk as the data, and /home, /var and /srv are excluded from root snapshots. A dead disk takes every snapshot with it. Use snapper for bad updates and a real backup (restic, borg or rsync to another machine) for your data.
Why does df show less free space than I expect?
Snapshots keep old versions of changed files, and df cannot see how btrfs shares blocks between snapshots. Use sudo btrfs filesystem usage / for the real picture, and delete old snapshots if they are the cause.
Can I roll back while the system is running?
Yes: sudo snapper rollback 41 makes a new read-write copy of snapshot 41 the default, and it takes effect at the next reboot. Booting the snapshot first is safer, because you see it work before you commit to it.