← All articles
INFRASTRUCTURE Self-Hosted Backups with BorgBackup and Restic: A Pr... 2026-02-09 · backup · borgbackup · restic

Self-Hosted Backups with BorgBackup and Restic: A Practical Comparison

Infrastructure 2026-02-09 backup borgbackup restic disaster-recovery storage

You're running a dozen self-hosted services. Immich has 50,000 irreplaceable family photos. Paperless-ngx holds years of scanned documents. Your Vaultwarden instance has every password you own. And it's all sitting on one machine.

If that disk dies tomorrow, what happens?

Self-hosting without backups is just renting time before a disaster. BorgBackup and Restic are the two most popular open-source backup tools in the homelab community, and they both solve this problem well — but differently.

Why Not Just rsync?

rsync copies files. That's it. It doesn't deduplicate, doesn't compress efficiently, doesn't encrypt, doesn't do versioning, and doesn't help you recover from ransomware or accidental deletion. You end up with a full copy of everything, every time, with no way to roll back.

BorgBackup and Restic are purpose-built backup tools that give you:

BorgBackup vs Restic

Feature BorgBackup Restic
Language Python/C Go
Deduplication Content-defined chunking Content-defined chunking
Encryption AES-256-CTR + HMAC-SHA256 AES-256-CTR + Poly1305
Compression lz4, zstd, zlib, lzma zstd (since 0.16)
Remote backends SSH only (native) S3, B2, SFTP, rclone, REST
Speed Faster for local/SSH Faster for cloud backends
Repo format Append-only capable Append-only capable
Mount backups FUSE mount FUSE mount
Windows support No Yes
Maturity 2010 (as attic) 2015
Parallel processing Single-threaded Multi-threaded

Choose BorgBackup if: You're backing up to a local NAS or another machine over SSH, want maximum compression options, and are Linux-only.

Choose Restic if: You want to back up to cloud storage (Backblaze B2, S3, etc.), need Windows support, or want simpler multi-backend configuration.

Setting Up BorgBackup

Install

# Debian/Ubuntu
sudo apt install borgbackup

# Fedora
sudo dnf install borgbackup

# Arch
sudo pacman -S borg

Create a repository

# Local repository
borg init --encryption=repokey /mnt/backup/borg-repo

# Remote repository (over SSH)
borg init --encryption=repokey user@backup-server:/path/to/repo

Save the encryption key somewhere safe:

borg key export /mnt/backup/borg-repo /safe/location/borg-key.txt

If you lose this key and the passphrase, your backups are gone forever.

Create a backup

borg create \
  /mnt/backup/borg-repo::'{hostname}-{now:%Y-%m-%d_%H:%M}' \
  /home \
  /etc \
  /var/lib/docker/volumes \
  --exclude '*.tmp' \
  --exclude '/home/*/.cache' \
  --compression zstd,3

Prune old backups

borg prune \
  /mnt/backup/borg-repo \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6

Automate with a script

#!/bin/bash
set -euo pipefail

export BORG_REPO="/mnt/backup/borg-repo"
export BORG_PASSPHRASE="your-passphrase"  # or use BORG_PASSCOMMAND

BACKUP_NAME="{hostname}-{now:%Y-%m-%d_%H:%M}"

echo "Starting backup..."
borg create \
  "::$BACKUP_NAME" \
  /home /etc /var/lib/docker/volumes \
  --exclude '*.tmp' \
  --exclude '/home/*/.cache' \
  --compression zstd,3 \
  --stats

echo "Pruning old backups..."
borg prune \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --stats

echo "Verifying repository..."
borg check

echo "Backup complete."

Run this daily via cron or a systemd timer.

Setting Up Restic

Install

# Debian/Ubuntu
sudo apt install restic

# Fedora
sudo dnf install restic

# Or download the binary
wget https://github.com/restic/restic/releases/latest/download/restic_linux_amd64.bz2
bunzip2 restic_linux_amd64.bz2
chmod +x restic_linux_amd64
sudo mv restic_linux_amd64 /usr/local/bin/restic

Create a repository

# Local
restic init --repo /mnt/backup/restic-repo

# Backblaze B2
export B2_ACCOUNT_ID="your-account-id"
export B2_ACCOUNT_KEY="your-account-key"
restic init --repo b2:bucket-name:restic

# S3-compatible
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
restic init --repo s3:s3.amazonaws.com/bucket-name/restic

Create a backup

restic backup \
  /home \
  /etc \
  /var/lib/docker/volumes \
  --exclude '*.tmp' \
  --exclude '/home/*/.cache' \
  --repo /mnt/backup/restic-repo

Browse and restore

# List snapshots
restic snapshots --repo /mnt/backup/restic-repo

# Restore a specific snapshot
restic restore latest --target /tmp/restore --repo /mnt/backup/restic-repo

# Mount and browse (FUSE)
restic mount /mnt/restic-browse --repo /mnt/backup/restic-repo

Forget old snapshots

restic forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune \
  --repo /mnt/backup/restic-repo

Building a 3-2-1 Backup Strategy

The 3-2-1 rule: 3 copies of your data, on 2 different storage types, with 1 copy off-site.

Here's how to implement it for a homelab:

Copy 1: Primary data

Your running services. This is where data lives day-to-day.

Copy 2: Local backup

BorgBackup or Restic to a separate drive or NAS on your local network. Fast to backup, fast to restore. Protects against single-disk failure.

Copy 3: Off-site backup

Restic to Backblaze B2, or BorgBackup to a remote server via SSH. Protects against fire, theft, or catastrophic hardware failure.

Cost for off-site: Backblaze B2 costs $6/TB/month for storage. A typical homelab with 500 GB of critical data costs about $3/month for off-site backup — cheap insurance.

Backing Up Docker Volumes

Most self-hosted services run in Docker. Their data lives in volumes:

# Find where volumes are stored
docker volume inspect my_volume | jq '.[0].Mountpoint'
# Usually: /var/lib/docker/volumes/my_volume/_data

# Backup all volumes
restic backup /var/lib/docker/volumes/ --repo /mnt/backup/restic-repo

Important: Some services (databases, especially) shouldn't be backed up by copying files while they're running. You'll get corrupted data. Instead:

# PostgreSQL (used by Immich, Gitea, etc.)
docker exec my-postgres pg_dumpall -U postgres > /tmp/pg-backup.sql

# MariaDB/MySQL
docker exec my-mariadb mysqldump -u root -p --all-databases > /tmp/mysql-backup.sql

# Then include the dump files in your backup

Monitoring Backups

A backup that silently fails is worse than no backup — it gives you false confidence. Set up monitoring:

Common Mistakes

  1. Never testing restores — A backup you haven't tested is a hope, not a plan. Regularly restore a file or directory to verify everything works.

  2. Backing up to the same disk — If the drive dies, you lose both the data and the backup.

  3. Not backing up encryption keys — Store your Borg/Restic repository key and passphrase somewhere safe (printed on paper, in a password manager, or on a separate USB drive).

  4. Skipping database dumps — Copying database files while the database is running often produces corrupt backups.

  5. No off-site copy — Local backups protect against hardware failure but not against fire, theft, or ransomware that encrypts everything on your network.

The Bottom Line

BorgBackup and Restic are both excellent, production-grade backup tools. BorgBackup has stronger compression and a longer track record; Restic has better cloud backend support and multi-threaded performance. Many people use both — Borg for local backups and Restic for cloud.

The best backup system is the one you actually set up and automate. Pick one, configure it, schedule it, and verify it regularly. Your future self will thank you the first time a drive dies or you accidentally delete something important.