Skip to content
Go back

Restic vs Borg vs Kopia: Backup Tools for People Who've Lost Data Before

By SumGuy 8 min read
Restic vs Borg vs Kopia: Backup Tools for People Who've Lost Data Before

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

Terminal window
# Install
apt install restic
# or
curl -L https://github.com/restic/restic/releases/latest/download/restic_linux_amd64.bz2 | bunzip2 > /usr/local/bin/restic
chmod +x /usr/local/bin/restic
# Initialize a local repository
restic init --repo /mnt/backup/myrepo
# Enter a password (and store it somewhere safe)
# Or initialize an S3 repository
export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret
restic init --repo s3:s3.amazonaws.com/mybucket/restic
# Or Backblaze B2
export B2_ACCOUNT_ID=your_account
export B2_ACCOUNT_KEY=your_key
restic init --repo b2:mybucket:restic

Running Backups

Terminal window
# Backup a directory
restic backup /home/user /etc --repo /mnt/backup/myrepo
# Backup with tags
restic backup /var/www --repo /mnt/backup/myrepo --tag web,daily
# Exclude patterns
restic backup /home/user --repo /mnt/backup/myrepo \
--exclude="*.log" \
--exclude=".cache" \
--exclude="node_modules"
# Verify repository integrity
restic check --repo /mnt/backup/myrepo

Restore and Browse

Terminal window
# List snapshots
restic snapshots --repo /mnt/backup/myrepo
# Browse snapshot contents
restic 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 snapshot
restic restore SNAPSHOT_ID --target /tmp/restore --repo /mnt/backup/myrepo
# Restore specific files
restic restore SNAPSHOT_ID --target /tmp/restore \
--include "/home/user/documents" \
--repo /mnt/backup/myrepo

Retention and Pruning

Terminal window
# Keep 7 daily, 4 weekly, 6 monthly snapshots
restic forget --repo /mnt/backup/myrepo \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
--prune

Automation Script

/usr/local/bin/restic-backup.sh
#!/bin/bash
export 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"
# Backup
restic backup /home /etc /var/www \
--exclude="*.log" \
--exclude=".cache" \
--exclude="**/node_modules" \
--tag daily
# Prune
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
# Verify
restic 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

Terminal window
# Install
apt 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-repo

Running Backups

Terminal window
# Create archive
borg 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 archives
borg list /mnt/backup/borg-repo
# Info about an archive
borg info /mnt/backup/borg-repo::archive-name

Borgmatic: The Right Way to Run Borg

Terminal window
# Install borgmatic
pip install borgmatic
# or
apt install borgmatic
# Generate config
borgmatic config generate > /etc/borgmatic/config.yaml
/etc/borgmatic/config.yaml
location:
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
Terminal window
# Run backup
borgmatic create --verbosity 1
# Restore
borgmatic restore --archive latest
# Schedule (add to crontab)
0 2 * * * /usr/local/bin/borgmatic create --verbosity 0 --syslog-verbosity 1

Docker with Borg

docker-compose.yml
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-stopped

Kopia: 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.

Terminal window
# Install
curl -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 repository
kopia repository create s3 \
--bucket=mybucket \
--access-key=KEY \
--secret-access-key=SECRET \
--prefix=kopia/
# Connect to existing repository
kopia repository connect s3 --bucket=mybucket --access-key=KEY --secret-access-key=SECRET

Running Backups

Terminal window
# Create a snapshot
kopia snapshot create /home/user
# List snapshots
kopia snapshot list
# Show snapshot content
kopia snapshot show SNAPSHOT_ID
# Restore
kopia snapshot restore SNAPSHOT_ID /tmp/restore
# Mount as FUSE
kopia mount all /tmp/kopia-mount

Retention Policies

Terminal window
# Set retention policy for a directory
kopia policy set /home/user \
--keep-latest 14 \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6
# Show policy
kopia policy show /home/user

Kopia Server (Web UI)

Terminal window
# Start Kopia server
kopia server start \
--address=0.0.0.0:51515 \
--server-username=admin \
--server-password=yourpassword
# Access at http://your-server:51515

The 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

FeatureResticBorgKopia
LanguageGoPython/CGo
PlatformsAllLinux/macOSAll
CompressionLZ4, ZstdLZ4, LZMA, ZstdZstd, LZ4, Gzip
DeduplicationYes (content-defined)Yes (content-defined)Yes (content-defined)
EncryptionYes (AES-256)Yes (AES-256)Yes (AES-256)
S3 backendYesVia rcloneYes (native)
B2 backendYes (native)Via rcloneYes (native)
SFTPYesYes (native)Yes
Web UINoNo (borgmatic has basic)Yes
Desktop appNoNoYes
Wrapper toolresticprofileborgmaticBuilt-in
SpeedFastFastFast
Compression qualityGoodExcellentGood
Learning curveLowMediumLow
Active developmentYesYesYes

The 3-2-1 Backup Strategy

No comparison is complete without the rule:

In practice for a home lab:

  1. Primary data (your NAS/server)
  2. Local backup (external drive or second server via Borg/Restic)
  3. Remote backup (Backblaze B2 or S3 via Restic/Kopia)
Terminal window
# Example: Restic to both local and B2
restic backup /home --repo /mnt/local-backup/myrepo --tag daily
restic 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.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Your Server Doesn't Know What Random Means (And That's a Problem)
Next Post
Docker Logging: From "Where Did My Logs Go?" to Centralized Bliss

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts