
ZFS Snapshots and Replication Backups on Linux Servers
- AuthorTimothy M.
- Date
- Time19 minutes
ZFS combines volume management, checksums, snapshots, and efficient replication. For VPS and dedicated hosts that store databases, object data, or VM images, snapshot-based backups recover faster than tar dumps alone. This guide builds a practical pool, automates snapshots, and replicates off-host.
Prerequisites
- Ubuntu/Debian server with unused disks or partitions for a data pool
- Second host or backup disk for replication targets
- Root access and awareness that wrong zpool create can wipe disks
Step 1: Install ZFS and Create a Pool
bash
sudo apt update
sudo apt install -y zfsutils-linux
# Example mirror pool — replace device names carefully
sudo zpool create -f tank mirror /dev/disk/by-id/DISK1 /dev/disk/by-id/DISK2
sudo zfs create tank/data
sudo zfs set compression=lz4 tank/data
sudo zfs set atime=off tank/data
sudo zpool status
df -h /tank/dataStep 2: Manual Snapshot Workflow
bash
sudo zfs snapshot tank/data@$(date +%Y%m%d-%H%M)
sudo zfs list -t snapshot
# Roll back a dataset (destructive to newer changes)
# sudo zfs rollback tank/data@20260803-1200Step 3: Automate Snapshots with systemd Timers
bash
sudo tee /usr/local/sbin/zfs-auto-snapshot.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
DS=tank/data
STAMP=$(date +%Y%m%d-%H%M)
zfs snapshot "\${DS}@auto-\${STAMP}"
# Keep last 48 hourly-style snapshots
zfs list -H -t snapshot -o name -s creation | grep "\${DS}@auto-" | head -n -48 | xargs -r zfs destroy
EOF
sudo chmod +x /usr/local/sbin/zfs-auto-snapshot.sh
sudo tee /etc/systemd/system/zfs-auto-snapshot.service >/dev/null <<'EOF'
[Unit]
Description=ZFS automatic snapshot for tank/data
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/zfs-auto-snapshot.sh
EOF
sudo tee /etc/systemd/system/zfs-auto-snapshot.timer >/dev/null <<'EOF'
[Unit]
Description=Run ZFS snapshots hourly
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now zfs-auto-snapshot.timerStep 4: Scrub for Bitrot Detection
bash
sudo zpool scrub tank
sudo zpool status tank
# Schedule monthly scrub
sudo tee /etc/systemd/system/zfs-scrub.timer >/dev/null <<'EOF'
[Unit]
Description=Monthly ZFS scrub
[Timer]
OnCalendar=monthly
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo tee /etc/systemd/system/zfs-scrub.service >/dev/null <<'EOF'
[Unit]
Description=Scrub ZFS pool tank
[Service]
Type=oneshot
ExecStart=/sbin/zpool scrub tank
EOF
sudo systemctl enable --now zfs-scrub.timerStep 5: Replicate with zfs send/receive
bash
# On backup host: create receiving pool/dataset first
# Initial full send
sudo zfs send tank/data@auto-20260803-1200 | ssh backup 'sudo zfs receive -F backup/tank-data'
# Incremental later
sudo zfs send -i tank/data@auto-20260803-1200 tank/data@auto-20260803-1300 \\
| ssh backup 'sudo zfs receive backup/tank-data'Production Checklist
- Snapshots are not offsite backups until replicated elsewhere.
- Monitor pool free space and fragmentation; alerts beat silent ENOSPC failures.
- Test rollback and receive restores on a non-production dataset.
- For databases, quiesce or use application-consistent dumps in addition to ZFS snapshots.
- Document disk by-id mappings so replacements do not guess the wrong device.
"ZFS snapshots make recovery fast; replication and restore drills make recovery real."



