Skip to content
SumGuy's Ramblings
Go back

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

# 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

# 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

# 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

# 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

#!/bin/bash
# /usr/local/bin/restic-backup.sh

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

# 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

# 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

# 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
# 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.

# 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

# 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

# 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)

# 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)
# 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:

Previous Post
Your Server Doesn't Know What Random Means (And That's a Problem)
Next Post
Cockpit vs Webmin: Managing Your Linux Server Without the Terminal (Sometimes)