Backup Strategies: Protecting Data with rsync, Borg, and Restic
A reliable backup strategy is non-negotiable. Hardware fails, ransomware strikes, and human error can wipe out years of data in seconds. This guide covers the three most popular Linux backup tools, automation with cron and systemd, and the principles that keep your data safe.
The 3-2-1 Rule
The foundation of any backup strategy:
- 3 copies of your data (the original plus two backups)
- 2 different storage media (local disk + remote/cloud)
- 1 copy offsite (geographically separate)
Following this rule ensures that no single failure -- fire, theft, disk crash, or ransomware -- can destroy all copies.
rsync
rsync is the workhorse for efficient file synchronisation. It transfers
only the differences between source and destination.
Basic Usage
# Sync a directory to a backup location
rsync -avz /srv/data/ /mnt/backup/data/
# Sync over SSH to a remote host
rsync -avz --delete /srv/data/ user@backup-host:/backups/data/
# Dry run -- see what would change without modifying anything
rsync -avz --delete --dry-run /srv/data/ /mnt/backup/data/
Flag reference:
- -a -- archive mode (recursive, preserves permissions, timestamps, etc.)
- -v -- verbose output
- -z -- compress data during transfer
- --delete -- remove files from destination that no longer exist in source
Exclude Patterns
rsync -avz --delete --exclude='*.tmp' --exclude='.cache/' --exclude-from='/etc/rsync-excludes.txt' /srv/data/ /mnt/backup/data/
Borg Backup
Borg provides deduplicating, compressed, encrypted backups. It is ideal for systems with many similar files or frequent backups of slowly changing data.
Initialize a Repository
# Local repository
borg init --encryption=repokey /mnt/backup/borg-repo
# Remote repository over SSH
borg init --encryption=repokey ssh://user@backup-host/backups/borg-repo
Create an Archive
borg create --stats --progress /mnt/backup/borg-repo::'{hostname}-{now:%Y-%m-%d_%H:%M}' /etc /home /srv --exclude '/home/*/.cache'
List and Prune Archives
# List all archives
borg list /mnt/backup/borg-repo
# Prune old archives (keep 7 daily, 4 weekly, 6 monthly)
borg prune --keep-daily=7 --keep-weekly=4 --keep-monthly=6 /mnt/backup/borg-repo
# Compact the repository to reclaim space after pruning
borg compact /mnt/backup/borg-repo
Restore
# Restore to a specific directory
cd /tmp/restore
borg extract /mnt/backup/borg-repo::myhost-2026-04-15_02:00
Restic
Restic is another deduplicating backup tool with native support for cloud storage backends (S3, B2, Azure, GCS).
Initialize a Repository
# Local repository
restic init --repo /mnt/backup/restic-repo
# S3 backend
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
restic init --repo s3:s3.amazonaws.com/my-backup-bucket
Create a Backup
restic backup --repo /mnt/backup/restic-repo /etc /home /srv --exclude-file=/etc/restic-excludes.txt --tag server-daily
List Snapshots
restic snapshots --repo /mnt/backup/restic-repo
Forget and Prune
# Apply a retention policy and remove old data
restic forget --repo /mnt/backup/restic-repo --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
Restore
restic restore latest --repo /mnt/backup/restic-repo --target /tmp/restore
Automation with Cron
Schedule backups with cron for set-and-forget reliability:
# /etc/cron.d/backup-daily
[email protected]
# Borg backup at 2:00 AM every day
0 2 * * * root /usr/local/bin/backup-borg.sh >> /var/log/borg-backup.log 2>&1
# rsync mirror at 3:00 AM
0 3 * * * root rsync -avz --delete /srv/ /mnt/backup/srv/ >> /var/log/rsync.log 2>&1
Automation with systemd
For more control, use a systemd timer:
# /etc/systemd/system/restic-backup.service
[Unit]
Description=Restic daily backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-restic.sh
Environment=RESTIC_REPOSITORY=/mnt/backup/restic-repo
Environment=RESTIC_PASSWORD_FILE=/etc/restic-password
# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run Restic backup daily
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl enable --now restic-backup.timer
Remote Backups
Over SSH
Both Borg and Restic support SSH natively. Set up key-based authentication
and optionally restrict the key to backup commands only in
~/.ssh/authorized_keys:
command="borg serve --restrict-to-path /backups",restrict ssh-ed25519 AAAA... backup-client
To S3-Compatible Storage
Restic supports S3 natively. For Borg, use a FUSE-mounted S3 bucket or
rclone as an intermediary.
Restore Testing
A backup you have never restored is a backup you do not have. Schedule quarterly restore drills:
#!/usr/bin/env bash
# restore-test.sh -- verify the latest backup is usable
set -euo pipefail
RESTORE_DIR=$(mktemp -d)
restic restore latest --repo /mnt/backup/restic-repo --target "$RESTORE_DIR"
# Verify key files exist
test -f "$RESTORE_DIR/etc/passwd"
test -d "$RESTORE_DIR/srv/data"
echo "Restore test PASSED"
rm -rf "$RESTORE_DIR"
Return to the DevOps hub or continue to Ansible Guide and Git for Sysadmins.