Off-host backup strategies — restic, borg, and rsnapshot compared
Snapshots in the LYLIX portal are great for "I made a change and broke something" but they live on the same storage pool as your VPS. If the pool fails, the snapshots fail with it. For real disaster recovery you need off-host backups — your data sitting on storage that isn't yours, ideally in a different geography. This article compares three popular tools (restic, borg, rsnapshot) and gives a quick-start recipe for each.
What "off-host backup" means in practice
- Your VPS reads its own data and writes it to a remote storage target — another server you control, a cloud- storage bucket, an external NAS, a friend's box.
- The transfer happens over the network, encrypted in transit.
- The target stores only your data — the original disk could catch fire and your backups would still be there.
- Some scheduled job (cron, systemd timer) runs the backup without human intervention.
Off-host backup is a different problem from snapshots; both are worth having, for different failure modes.
The three tools — what they're good at
| restic | borg | rsnapshot | |
|---|---|---|---|
| Style | Modern dedupe + encryption | Modern dedupe + encryption | rsync + hardlinks |
| Storage targets | S3, B2, Azure, GCS, SFTP, local, REST | SSH (with borg installed remote), local | SSH, local — file-level |
| Encryption | AES-256, by default | AES-256, by default | None (use SSH for transit; not at rest) |
| Dedupe | Content-defined chunks; excellent | Content-defined chunks; excellent | File-level (hardlinks); poor for files that change |
| Cross-platform | Linux, macOS, Windows, BSD | Linux, macOS, BSD (Windows experimental) | Linux, BSD |
| Speed restore single file | Good (indexed) | Good (indexed) | Instant (it's just a file on disk) |
| Best for | S3-style buckets, multi-machine, simplicity | SSH-only targets, tightest dedupe | Browsing backups directly, simple stacks |
Pick restic if you're using cloud object storage (Backblaze B2, AWS S3, or compatible). It's the most modern, actively developed, and target-flexible.
Pick borg if you have SSH access to a remote Linux box you control. Marginally tighter dedupe than restic; very proven on Linux.
Pick rsnapshot if you want backups you can browse directly with cd, ls, and scp. No encryption, no dedupe — but no surprises either, and recovery is just file copy.
Quick start — restic to Backblaze B2
Backblaze B2 is the cheapest mainstream object-storage option (~$0.006/GB/month at the time of writing); restic supports it natively.
# Install restic:
apt install -y restic # Debian / Ubuntu
dnf install -y restic # AlmaLinux
# Configure environment (put in a root-only file):
export B2_ACCOUNT_ID=your-key-id
export B2_ACCOUNT_KEY=your-application-key
export RESTIC_REPOSITORY=b2:your-bucket-name:vps-backup
export RESTIC_PASSWORD=long-random-passphrase-for-encryption
# Initialize the repository (once):
restic init
# Run your first backup:
restic backup /etc /home /var/www
# Verify it:
restic snapshots
restic check
Restore:
# List snapshots:
restic snapshots
# Restore a snapshot to a directory:
restic restore latest --target /tmp/restore
# Restore a single file:
restic restore latest --target /tmp/restore --include /etc/nginx/nginx.conf
Schedule via systemd timer or cron — daily 02:00:
# /etc/cron.daily/backup
#!/bin/sh
export B2_ACCOUNT_ID=...
export B2_ACCOUNT_KEY=...
export RESTIC_REPOSITORY=b2:...
export RESTIC_PASSWORD=...
restic backup /etc /home /var/www --tag daily
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
The forget --keep-* --prune line is the retention policy: 7 daily, 4 weekly, 12 monthly. Restic prunes old data automatically.
Quick start — borg to a remote SSH target
Assume you have SSH access to a backup target box at backup.example.com, with borg installed on both sides.
# Install borg on the VPS:
apt install -y borgbackup # Debian / Ubuntu
dnf install -y borgbackup # AlmaLinux (EPEL)
# On the backup target, create a user for backups:
useradd -m -s /bin/bash borguser
# Add your VPS's SSH public key to /home/borguser/.ssh/authorized_keys
# On the VPS, init the remote repo:
export BORG_PASSPHRASE=long-random-passphrase
borg init --encryption=repokey-blake2 ssh://borguser@backup.example.com/~/vps-backup
# Run the first backup:
borg create ssh://borguser@backup.example.com/~/vps-backup::$(date +%Y-%m-%d-%H%M%S) \
/etc /home /var/www
# List backups:
borg list ssh://borguser@backup.example.com/~/vps-backup
Schedule and retention same idea as restic:
borg create ssh://...::$(date +%Y-%m-%d-%H%M%S) /etc /home /var/www
borg prune ssh://... --keep-daily 7 --keep-weekly 4 --keep-monthly 12
Quick start — rsnapshot to a remote SSH target
rsnapshot is rsync + hardlinks. Each "snapshot" is a complete directory tree, but unchanged files are hardlinks to the previous snapshot — so the disk usage is closer to one full + many deltas.
# Install on the VPS (the source of backups):
apt install -y rsnapshot # Debian / Ubuntu
dnf install -y rsnapshot # AlmaLinux (EPEL)
# Edit /etc/rsnapshot.conf:
# snapshot_root /backup/rsnapshot/
# retain daily 7
# retain weekly 4
# retain monthly 12
# backup /etc/ localhost/
# backup /home/ localhost/
# backup /var/www/ localhost/
# Test the config:
rsnapshot configtest
# Run a daily backup:
rsnapshot daily
Schedule via cron:
# /etc/cron.d/rsnapshot
0 2 * * * root rsnapshot daily
0 3 * * 0 root rsnapshot weekly
0 4 1 * * root rsnapshot monthly
For off-host: set snapshot_root to a remote mount (NFS, sshfs) and the data lands off-host. Or write your own pre/ post scripts that rsync the rsnapshot tree to a remote box after each run.
(rsnapshot doesn't have a built-in remote backend — the patterns above are the workarounds.)
What to back up — the practical list
- /etc — all system config. Critical.
- /home — user files, SSH keys, dotfiles.
- /var/www — web content if applicable.
- /var/lib/mysql or /var/lib/postgresql — but only if you snapshot the database first with
mysqldump/pg_dumpall. Don't back up the raw datadir while the DB is running. - /srv — wherever you put application data.
- SKIP /proc, /sys, /dev, /tmp, /run — these are virtual filesystems or ephemeral.
- SKIP /var/cache — regenerable.
- SKIP /var/log usually — large and non-essential. Keep
/var/log/auth.logfor post-incident review if you want.
Database backups specifically
Hot-backing up a running database is unreliable. Add a pre- backup step that dumps the database to a file, back up the file:
# MySQL / MariaDB:
mysqldump --all-databases | gzip > /backup/mysql-$(date +%F).sql.gz
# PostgreSQL:
sudo -u postgres pg_dumpall | gzip > /backup/postgres-$(date +%F).sql.gz
# Then back up /backup/ with your tool of choice.
Test your restore — quarterly minimum
An untested backup is no backup. Pick a random snapshot, restore a few files to a temp dir, confirm they're intact:
restic restore latest --target /tmp/restore-test
diff -r /etc /tmp/restore-test/etc | head
If you've never restored, you don't know if your backups work. Find out before you need them.
Cost ballpark for a small VPS
For ~20 GB of data, backed up daily with reasonable retention:
- Backblaze B2: ~$1-2/month (storage) + tiny per-month egress for restores.
- Your own remote Linux box: free if you have the box; pay only for the storage there.
- AWS S3 Glacier Deep Archive: cheaper per GB but slower to restore; reasonable for monthly archives, not for daily.
For most LYLIX customers, restic + Backblaze B2 is the right default. Fast to set up, cheap to run, works.
Also Read
Powered by WHMCompleteSolution