Ubuntu System Backup: Don’t Wait Until You’ve Lost Data to Learn Your Lesson
I’ve set up Ubuntu Server 22.04 on over 20 VPS instances, and I always start with one thing — configuring automatic snapshots, before installing anything else. The reason is simple: one apt upgrade that touched the kernel cost me nearly 3 hours of manual recovery from rescue mode. From that point on, Btrfs snapshots became step one in my server setup checklist.
Comparing Popular Backup Approaches on Ubuntu
Before settling on Btrfs + Snapper, I tried three different approaches. Each looked fine on paper — but real-world server use revealed the gaps.
1. rsync — Traditional File Backup
rsync is familiar, easy to script, and requires minimal setup. But it falls short in the most critical areas:
- Not a true snapshot — it doesn’t capture system state at a precise point in time
- Slow recovery: you have to copy everything back, which takes a long time
- Can’t roll back the bootloader if the kernel breaks or GRUB gets corrupted
- Backup size grows with partition size — not storage-efficient
2. Timeshift — Easy to Use but Lacking Flexibility
At first glance, Timeshift looks better: a friendly GUI that supports both rsync mode and Btrfs mode. In practice on a server:
- rsync mode is still as slow and storage-hungry as plain rsync
- Btrfs mode only snapshots
/and/home, with limited customization - No automatic
aptintegration — you have to remember to create snapshots manually before updating - The cleanup policy is fairly basic and less flexible than Snapper
3. Btrfs + Snapper — Filesystem-Level Snapshots
This is what I run on all my critical servers. Snapshots work at the filesystem level, not file by file. They’re instant — under a second, regardless of partition size. Only changes are stored going forward, with no full duplication. And you can roll back directly from the GRUB boot menu, even when the system won’t boot at all.
Btrfs + Snapper: Pros and Cons
Real-World Advantages
- Near-instant snapshots: Copy-on-write filesystem — creating a snapshot requires no data copying
- Storage-efficient: Snapshots only store changes from the previous state — no full duplication
- GRUB rollback: Even when the system won’t boot, you can select an older snapshot from the boot menu
- Fully automated: Timeline snapshots by hour/day/week, with a cleanup policy that automatically removes old snapshots
- apt hook integration: Automatically snapshots before and after every
apt install/upgrade— no manual effort needed
Drawbacks to Know Before Deploying
- The partition must be formatted as Btrfs during Ubuntu installation — converting from ext4 is not straightforward
- You need to understand Btrfs subvolumes (not complex, but worth reading up on)
- Snapshots live on the same disk as the system — they’re not a true backup if the disk physically fails
- Running databases (MySQL, PostgreSQL) need separate backups — filesystem snapshots don’t guarantee consistency
Which Approach Should You Choose?
A quick summary for each use case:
- Production server, need fast rollback when an update breaks things → Btrfs + Snapper (this guide)
- Ubuntu desktop, need simple /home backup → Timeshift rsync mode is easier
- Backing up data to another server or cloud → rsync, restic, or borgbackup
The rest of this guide focuses specifically on Btrfs + Snapper for Ubuntu Server.
Step-by-Step Setup Guide
Prerequisite: Ubuntu Installed with Btrfs
When installing Ubuntu 22.04, at the disk selection step choose Custom Storage Layout → format the root partition as Btrfs. The Ubuntu Installer will automatically create the @ subvolume for root and @home for /home.
Check whether your current system is already using Btrfs:
df -T /
# The Type column must show btrfs
sudo btrfs subvolume list /
# You should see subvolumes @ and @home
Step 1: Install Snapper and snapper-support
sudo apt update
sudo apt install -y snapper snapper-support
snapper-support pulls in grub-btrfs — which automatically adds snapshot entries to the GRUB boot menu.
Step 2: Create a Snapper Configuration for Root
sudo snapper -c root create-config /
# Check the newly created configuration
sudo snapper -c root get-config
Step 3: Adjust the Snapshot Retention Policy
The default Snapper settings keep too many snapshots — if you don’t tune them, storage fills up faster than you’d expect. Here’s what I typically set:
sudo nano /etc/snapper/configs/root
Find and update the following lines:
# Maximum number of manual snapshots to keep
NUMBER_LIMIT="5"
# Enable automatic timeline snapshot creation and cleanup
TIMELINE_CREATE="yes"
TIMELINE_CLEANUP="yes"
# Number of snapshots to retain per time period
TIMELINE_LIMIT_HOURLY="3"
TIMELINE_LIMIT_DAILY="5"
TIMELINE_LIMIT_WEEKLY="2"
TIMELINE_LIMIT_MONTHLY="1"
TIMELINE_LIMIT_YEARLY="0"
Step 4: Enable Snapper Timers
sudo systemctl enable --now snapper-timeline.timer
sudo systemctl enable --now snapper-cleanup.timer
# Check that the timer is running
sudo systemctl status snapper-timeline.timer
Step 5: Install apt-btrfs-snapper for Automatic Pre-apt Snapshots
This is my favorite part of the whole setup. Every time you run apt install or apt upgrade, the system automatically creates a snapshot before and after — no manual intervention required:
sudo apt install -y apt-btrfs-snapper
# Test it right away: install a package and watch snapshots get created automatically
sudo apt install -y htop
sudo snapper -c root list
# You should see 2 new snapshots: "pre" and "post" from the last apt run
Step 6: Update GRUB to Add Snapshots to the Boot Menu
sudo update-grub
# Check if grub-btrfs has generated boot entries
grep -i btrfs /boot/grub/grub.cfg | head -5
From now on, at boot time GRUB will show an additional “Ubuntu Snapshots” submenu listing your snapshots to boot into.
How to Roll Back When Things Go Wrong
Rolling Back from a Running System
# View the list of current snapshots
sudo snapper -c root list
# ID | Type | Date | Description
# 0 | single | 2026-10-08 10:00:00 +0900 | current
# 1 | pre | 2026-10-08 11:00:00 +0900 | apt: apt-get upgrade
# 2 | post | 2026-10-08 11:05:00 +0900 | apt: apt-get upgrade
# View which files changed between snapshot 1 and the current state
sudo snapper -c root diff 1..0
# Roll back to snapshot 1 (undo all changes made since then)
sudo snapper -c root undochange 1..0
Rolling Back When the System Won’t Boot
- Restart the machine and enter the GRUB menu (hold
Shiftor pressEsc) - Select Ubuntu Snapshots → choose the snapshot you want to roll back to
- The system boots into that snapshot (read-only, for inspection)
- Once you’re in, run the following commands to perform the actual rollback and reboot:
# Roll back to snapshot ID 5 (replace with the ID from your list)
sudo snapper -c root rollback 5
sudo reboot
Managing Snapshots Manually
# Create a manual snapshot before making any important changes
sudo snapper -c root create --description "before-installing-docker"
# View total storage used by Btrfs
sudo btrfs filesystem usage /
# Delete a manual snapshot that's no longer needed
sudo snapper -c root delete 3
# Delete multiple snapshots at once
sudo snapper -c root delete 3 4 5
Practical Tips from Long-Term Use
- Snapshot ≠ full backup: Snapshots live on the same disk as your system — if the disk physically fails, the snapshots are gone too. For critical data (databases, uploads), you still need rsync or restic to back up to an external location.
- Monitor storage regularly: Run
btrfs filesystem usage /once a month. CoW snapshots accumulate over time — the cleanup timer handles it, but a periodic check never hurts. - Snapshot /home separately: If you want to also snapshot /home, create an additional config:
sudo snapper -c home create-config /homeand adjust the policy the same way. - Database consistency: Running MySQL or PostgreSQL instances are not guaranteed to be in a consistent state when a filesystem snapshot is taken. For production databases, supplement with
mysqldumporpg_dumpon a separate cron schedule.
This setup takes about 15 minutes but has saved me more times than I can count — especially when apt full-upgrade touches the kernel or a critical system library. After a rollback, the server is back to a clean state in under 2 minutes, with no need to dig through rescue mode or reinstall.

