The Backup You Didn’t Make Is the One You’ll Need
Let’s skip the sermon about why backups matter. If you’re reading this, you either already know or you recently found out in the most inconvenient way possible. The question isn’t whether to back up — it’s which tool makes it likely you’ll actually do it consistently and reliably.
Three tools dominate the modern Linux backup landscape for self-hosters and home lab operators: Restic, Borg, and Kopia. All three use deduplication — the technique that means backing up the same data twice doesn’t double your storage usage. All three encrypt data at rest. All three are actively maintained in 2026. They differ in language, approach, backend support, and how much they’ll frustrate you.
Why Deduplication Matters
Without deduplication, a daily backup of a 100GB directory gives you 365 × 100GB = 36.5TB per year. With deduplication, your backup repository only stores unique chunks of data. If 95GB of your data doesn’t change between backups, each backup adds about 5GB of new data. Total storage: much more reasonable.
Deduplication works by splitting files into chunks, hashing each chunk, and only storing chunks that haven’t been seen before. Each “snapshot” (backup point in time) is really just a set of references to the chunks that make it up. This is also why restorations are fast — the tool assembles the snapshot by reading only the chunks it needs.
The practical implication: you can keep 90 days of daily backups for a server where data changes slowly, and the storage cost is much closer to 1× than 90× the data size.
Restic: The Crossplatform Workhorse
Restic is written in Go, runs on every platform that matters (Linux, macOS, Windows, *BSD), and has the most backends of any backup tool in this comparison. If you need to back up to S3, Backblaze B2, SFTP, rclone destinations, Azure Blob, or a local path, Restic handles all of it with the same CLI.
Getting Started
# Installapt install restic# orcurl -L https://github.com/restic/restic/releases/latest/download/restic_linux_amd64.bz2 | bunzip2 > /usr/local/bin/resticchmod +x /usr/local/bin/restic
# Initialize a local repositoryrestic init --repo /mnt/backup/myrepo# Enter a password (and store it somewhere safe)
# Or initialize an S3 repositoryexport AWS_ACCESS_KEY_ID=your_keyexport AWS_SECRET_ACCESS_KEY=your_secretrestic init --repo s3:s3.amazonaws.com/mybucket/restic
# Or Backblaze B2export B2_ACCOUNT_ID=your_accountexport B2_ACCOUNT_KEY=your_keyrestic init --repo b2:mybucket:resticRunning Backups
# Backup a directoryrestic backup /home/user /etc --repo /mnt/backup/myrepo
# Backup with tagsrestic backup /var/www --repo /mnt/backup/myrepo --tag web,daily
# Exclude patternsrestic backup /home/user --repo /mnt/backup/myrepo \ --exclude="*.log" \ --exclude=".cache" \ --exclude="node_modules"
# Verify repository integrityrestic check --repo /mnt/backup/myrepoRestore and Browse
# List snapshotsrestic snapshots --repo /mnt/backup/myrepo
# Browse snapshot contentsrestic ls --repo /mnt/backup/myrepo SNAPSHOT_ID
# Mount repository as FUSE filesystem (browse like a directory)restic mount --repo /mnt/backup/myrepo /tmp/restic-mount
# Restore specific snapshotrestic restore SNAPSHOT_ID --target /tmp/restore --repo /mnt/backup/myrepo
# Restore specific filesrestic restore SNAPSHOT_ID --target /tmp/restore \ --include "/home/user/documents" \ --repo /mnt/backup/myrepoRetention and Pruning
# Keep 7 daily, 4 weekly, 6 monthly snapshotsrestic forget --repo /mnt/backup/myrepo \ --keep-daily 7 \ --keep-weekly 4 \ --keep-monthly 6 \ --pruneAutomation Script
#!/bin/bashexport RESTIC_REPOSITORY="s3:s3.amazonaws.com/mybucket/restic"export RESTIC_PASSWORD="your-encrypted-password"export AWS_ACCESS_KEY_ID="your_key"export AWS_SECRET_ACCESS_KEY="your_secret"
# Backuprestic backup /home /etc /var/www \ --exclude="*.log" \ --exclude=".cache" \ --exclude="**/node_modules" \ --tag daily
# Prunerestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
# Verifyrestic check
echo "Backup completed: $(date)"Borg: The Compression Champion
BorgBackup (Borg) is written in Python and C, focused on Linux/macOS, and features exceptional compression. Borg uses LZ4, zlib, LZMA, and zstd compression algorithms. For text-heavy data (logs, code, configs), Borg’s compression ratios are often significantly better than Restic’s.
Borg’s killer feature for many users is borgmatic — a wrapper that handles configuration, scheduling, and alerting, so your entire backup policy lives in a YAML file.
Getting Started with Borg
# Installapt install borgbackup
# Initialize repository (local)borg init --encryption=repokey /mnt/backup/borg-repo# Set a passphrase
# Initialize remote (over SSH)borg init --encryption=repokey user@backup-server:/mnt/backup/borg-repoRunning Backups
# Create archiveborg create /mnt/backup/borg-repo::'{hostname}-{now:%Y-%m-%d}' \ /home /etc \ --exclude '*.log' \ --exclude '**/.cache' \ --compression lz4 # or zstd,9 for better compression
# List archivesborg list /mnt/backup/borg-repo
# Info about an archiveborg info /mnt/backup/borg-repo::archive-nameBorgmatic: The Right Way to Run Borg
# Install borgmaticpip install borgmatic# orapt install borgmatic
# Generate configborgmatic config generate > /etc/borgmatic/config.yamllocation: source_directories: - /home - /etc - /var/www repositories: - path: /mnt/backup/borg-repo label: local - path: user@backup-server:/mnt/backup/borg-repo label: remote
storage: encryption_passphrase: "your-passphrase" compression: lz4 archive_name_format: '{hostname}-{now:%Y-%m-%d_%H-%M-%S}'
retention: keep_daily: 7 keep_weekly: 4 keep_monthly: 6
consistency: checks: - name: repository - name: archives check_last: 3
hooks: before_backup: - echo "Starting backup at $(date)" after_backup: - echo "Backup completed at $(date)" on_error: - echo "Backup FAILED at $(date)" | mail -s "Backup Error" admin@example.com# Run backupborgmatic create --verbosity 1
# Restoreborgmatic restore --archive latest
# Schedule (add to crontab)0 2 * * * /usr/local/bin/borgmatic create --verbosity 0 --syslog-verbosity 1Docker with Borg
services: borgmatic: image: b3vis/borgmatic volumes: - /home:/mnt/source/home:ro - /etc:/mnt/source/etc:ro - /mnt/backup:/mnt/backup - ./borgmatic.yaml:/etc/borgmatic.d/config.yaml:ro environment: - TZ=America/New_York - BORGMATIC_CRON_SCHEDULE=0 2 * * * restart: unless-stoppedKopia: The New Kid With a Web UI
Kopia is the newest of the three, written in Go like Restic, but adding a web UI and desktop application that the others lack. It’s excellent for mixed environments where you want server-side automation and a GUI for desktop backup management.
# Installcurl -s https://kopia.io/docs/installation/linux-install-source.sh | bash# or download from GitHub releases
# Initialize repository (local)kopia repository create filesystem --path /mnt/backup/kopia-repo
# Initialize S3 repositorykopia repository create s3 \ --bucket=mybucket \ --access-key=KEY \ --secret-access-key=SECRET \ --prefix=kopia/
# Connect to existing repositorykopia repository connect s3 --bucket=mybucket --access-key=KEY --secret-access-key=SECRETRunning Backups
# Create a snapshotkopia snapshot create /home/user
# List snapshotskopia snapshot list
# Show snapshot contentkopia snapshot show SNAPSHOT_ID
# Restorekopia snapshot restore SNAPSHOT_ID /tmp/restore
# Mount as FUSEkopia mount all /tmp/kopia-mountRetention Policies
# Set retention policy for a directorykopia policy set /home/user \ --keep-latest 14 \ --keep-daily 7 \ --keep-weekly 4 \ --keep-monthly 6
# Show policykopia policy show /home/userKopia Server (Web UI)
# Start Kopia serverkopia server start \ --address=0.0.0.0:51515 \ --server-username=admin \ --server-password=yourpassword
# Access at http://your-server:51515The web UI shows repository statistics, allows browsing snapshots, and initiates restores — genuinely useful for non-technical users who need to recover their own files.
The Comparison Table
| Feature | Restic | Borg | Kopia |
|---|---|---|---|
| Language | Go | Python/C | Go |
| Platforms | All | Linux/macOS | All |
| Compression | LZ4, Zstd | LZ4, LZMA, Zstd | Zstd, LZ4, Gzip |
| Deduplication | Yes (content-defined) | Yes (content-defined) | Yes (content-defined) |
| Encryption | Yes (AES-256) | Yes (AES-256) | Yes (AES-256) |
| S3 backend | Yes | Via rclone | Yes (native) |
| B2 backend | Yes (native) | Via rclone | Yes (native) |
| SFTP | Yes | Yes (native) | Yes |
| Web UI | No | No (borgmatic has basic) | Yes |
| Desktop app | No | No | Yes |
| Wrapper tool | resticprofile | borgmatic | Built-in |
| Speed | Fast | Fast | Fast |
| Compression quality | Good | Excellent | Good |
| Learning curve | Low | Medium | Low |
| Active development | Yes | Yes | Yes |
The 3-2-1 Backup Strategy
No comparison is complete without the rule:
- 3 copies of your data
- 2 different storage media types
- 1 copy offsite
In practice for a home lab:
- Primary data (your NAS/server)
- Local backup (external drive or second server via Borg/Restic)
- Remote backup (Backblaze B2 or S3 via Restic/Kopia)
# Example: Restic to both local and B2restic backup /home --repo /mnt/local-backup/myrepo --tag dailyrestic backup /home --repo b2:mybucket:restic --tag daily
# Or Borgmatic with two repo targets (local + remote SSH)Which One Should You Use?
Use Restic if: You want the widest backend support, cross-platform operation, and a simple CLI without wrappers. Best for scripted server backups with cloud storage.
Use Borg if: You’re on Linux, care about compression ratios, and want borgmatic’s YAML-driven policy management. Best for backing up large amounts of text/log data or when storage is at a premium.
Use Kopia if: You want a web UI, you’re managing a mixed fleet of servers and desktops, or you want a single tool that works on both your server and your partner’s laptop.
All three beat not having backups. Pick one, automate it, test your restores (this part is crucial — a backup you’ve never tested is a guess, not a safety net), and go do something else with your weekend.