Backup strategies

BorgBackup, rsync and making sure data actually survives a server failure.

Server backups with BorgBackup and remote storage

BorgBackup gives you deduplication, encryption, and compression in a single tool. A full backup of a 20GB server might take 5 minutes the first time and 30 seconds every day after that because only changed blocks are stored.

Initialize a remote repository

borg init --encryption=repokey user@backup-server:/backups/myserver

Save the passphrase somewhere safe — without it the backup is unreadable.

Create a backup

borg create \
  --compression lz4 \
  --exclude /proc \
  --exclude /sys \
  --exclude /dev \
  --exclude /run \
  user@backup-server:/backups/myserver::$(date +%Y-%m-%d) \
  /

Prune old backups

borg prune \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  user@backup-server:/backups/myserver

This keeps daily backups for a week, weekly for a month, and monthly for six months. Put both commands in a script and run it from cron or a systemd timer.

Test your restore process before you need it. borg extract user@backup-server:/backups/myserver::2025-06-20 path/to/file

Incremental backups with rsync and hard links

If Borg is overkill for your use case, rsync with hard links gives you incremental backups using only tools already on every Linux server.

How it works

Each backup is a full directory snapshot. Files that haven't changed are hard links to the previous backup — they take no additional space. Files that have changed are new copies. You can browse any backup as a normal directory.

#!/bin/bash
DEST="/backups"
SRC="/var/www"
DATE=$(date +%Y-%m-%d)
LATEST="$DEST/latest"

rsync -av --delete \
  --link-dest="$LATEST" \
  "$SRC/" \
  "$DEST/$DATE/"

rm -f "$LATEST"
ln -s "$DEST/$DATE" "$LATEST"

Remote backups

rsync works over SSH. Replace the destination with a remote path:

rsync -av --delete \
  --link-dest=user@remote:/backups/latest \
  /var/www/ \
  user@remote:/backups/$(date +%Y-%m-%d)/

Set up SSH key auth first so the script can run unattended.