LinuxXLVIII · Backup ToolsFS snapshots
Filesystem snapshots as backup - ZFS and btrfs
What you'll learn
- Use ZFS snapshots for backup
- Use btrfs snapshots for backup
- Distinguish crash-consistent from application-consistent
- Send snapshots offsite
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09
ZFS and btrfs have built-in snapshots. They are fast, space-efficient, and easy to send offsite. This lesson covers both for backup.
ZFS snapshots
ZFS snapshots are instant and space-efficient (copy-on- write).
# Create a snapshot
zfs snapshot tank/data@backup-2026-08-09
# List snapshots
zfs list -t snapshot
# Access a snapshot (read-only)
mkdir /mnt/snap
mount -t zfs tank/data@backup-2026-08-09 /mnt/snap
# Send to a file (for backup)
zfs send tank/data@backup-2026-08-09 > /backup/zfs-snap.zfs
# Receive on another host
zfs receive tank/data < /backup/zfs-snap.zfs
# Incremental send (only changes since last snapshot)
zfs send -i tank/data@previous tank/data@latest | zfs receive tank/data
btrfs snapshots
btrfs has similar capabilities:
# Create a snapshot
btrfs subvolume snapshot -r /data /data/.snap-2026-08-09
# List snapshots
btrfs subvolume list -s /
# Send to a file
btrfs send /data/.snap-2026-08-09 > /backup/btrfs-snap.btrfs
# Receive
btrfs receive /restore/ < /backup/btrfs-snap.btrfs
btrfs is included in the kernel. ZFS requires a separate module (DKMS or OpenZFS).
Distinguish snapshot types
ZFS and btrfs snapshots are crash-consistent: the filesystem is consistent, but the application may have been mid-write.
For databases, the backup bracket must live in a single
client session. Two separate psql -c calls do not work: the
first client disconnects, PostgreSQL aborts the backup, and
the snapshot taken in between has no backup_label.
set -euo pipefail
psql -v ON_ERROR_STOP=1 <<'SQL'
SELECT pg_backup_start('zfs-snap', fast => true);
\! zfs snapshot tank/data@backup
SELECT * FROM pg_backup_stop();
SQL
set -euo pipefail and -v ON_ERROR_STOP=1 are load-bearing,
not boilerplate. Without them a failed pg_backup_start() still
lets zfs snapshot run, and the job reports success while
handing you a crash-consistent snapshot your runbook calls
application-consistent.
For most modern databases with WAL, crash-consistent snapshots work because the database recovers as if from a crash. That is usually the right trade: a ZFS snapshot plus WAL archiving beats a hand-rolled bracket you got wrong.
Send snapshots offsite
Both ZFS and btrfs support sending snapshots to another host:
# ZFS incremental send
zfs send -i tank/data@yesterday tank/data@today | \
ssh backup@offsite "zfs receive tank/data"
# btrfs incremental send
btrfs send -p /data/.snap-prev /data/.snap-today | \
ssh backup@offsite "btrfs receive /backup/data"
Incremental sends only transfer changed blocks. After the first full send, daily sends are small.
When to use
ZFS/btrfs snapshots are best for:
- Filesystem-level backup.
- Fast snapshots (instant).
- Offsite replication.
- Database hosts, when the quiesce is held in one session.
Not best for:
- Non-ZFS, non-btrfs filesystems.
- Off-host backups (the snapshot is on the same host).
- Encryption at rest (must be configured separately).
Knowledge check
Knowledge check · 3 questions
Q1. What kind of consistency do ZFS snapshots provide?
Q2. A ZFS snapshot on the same host is a complete backup.
Q3. Which of the following are valid ZFS snapshot commands? Select all that apply.
Passing score: 75%. Answers are checked in this browser.