FreeBSD.software
Home/Guides/BorgBackup vs Restic: Backup Tool Comparison on FreeBSD
comparison·2026-04-09·12 min read

BorgBackup vs Restic: Backup Tool Comparison on FreeBSD

Compare BorgBackup and Restic on FreeBSD: deduplication, encryption, performance, cloud backends, pruning, and which backup tool to choose for your FreeBSD server.

BorgBackup vs Restic: Backup Tool Comparison on FreeBSD

BorgBackup and Restic are the two most popular deduplicating backup tools for FreeBSD. Both encrypt your data, both deduplicate efficiently, and both support incremental backups. But they differ in architecture, backend support, performance characteristics, and operational workflow.

This guide provides a thorough comparison based on real-world usage on FreeBSD systems. We cover deduplication, encryption, performance, cloud backend support, pruning, restore workflows, and operational considerations.

For the broader backup landscape on FreeBSD, see our Best Backup Solutions for FreeBSD guide.

TL;DR -- Quick Verdict

Choose BorgBackup if: You back up to a server you control via SSH, want the best deduplication ratio, need borg mount for browsing backups, and prefer a mature tool with a large user base.

Choose Restic if: You back up directly to cloud storage (S3, B2, GCS, Azure), want a single Go binary with no dependencies, need cross-platform repository compatibility, or prefer a simpler mental model.

Both are excellent. You will not go wrong with either.

Head-to-Head Comparison

| Feature | BorgBackup | Restic |

|---|---|---|

| Package | archivers/py-borgbackup | sysutils/restic |

| Language | Python + C (critical paths) | Go |

| Binary | Requires Python runtime | Single static binary |

| Repository format | Borg-specific | Restic-specific |

| Deduplication | Variable-length chunking (Buzhash) | Content-defined chunking (Rabin) |

| Avg. dedup ratio | Excellent (slightly better) | Excellent |

| Encryption | AES-256-CTR + HMAC-SHA256 | AES-256-GCM (AEAD) |

| Key management | Repokey or keyfile | Repository password |

| Compression | lz4, zstd, zlib, lzma, none | Auto (zstd), or none |

| Compression control | Per-archive, per-file patterns | Global only |

| SSH backend | Yes (borg serve) | Yes (SFTP) |

| S3 | No (rclone workaround) | Native |

| Backblaze B2 | No (rclone workaround) | Native |

| Azure Blob | No (rclone workaround) | Native |

| Google Cloud Storage | No (rclone workaround) | Native |

| REST server | No | Yes (rest-server) |

| FUSE mount | Yes (borg mount) | Yes (restic mount) |

| Append-only mode | Yes (borg serve --append-only) | Yes (rest-server --append-only) |

| Parallel operations | Limited | Better (Go goroutines) |

| Lock handling | Advisory locks | Lock files (stale lock issues) |

| Prune speed | Fast | Slower on cloud backends |

| Check/verify | borg check | restic check |

| Active development | Yes | Yes |

| FreeBSD support | Excellent | Excellent |

Installation on FreeBSD

BorgBackup

sh
# Install BorgBackup pkg install py311-borgbackup # Verify installation borg --version # borg 1.4.x # Optional: install borgmatic for configuration management pkg install py311-borgmatic

Restic

sh
# Install Restic pkg install restic # Verify installation restic version # restic 0.17.x

Restic's single binary is notably simpler to deploy. No Python runtime, no library dependencies. Copy the binary to a FreeBSD server and it works.

Repository Initialization

BorgBackup

sh
# Local repository borg init --encryption=repokey /backup/borg-repo # Remote repository via SSH borg init --encryption=repokey ssh://backup@remote-server:22/backup/borg-repo # Encryption modes: # repokey - key stored in repo, protected by passphrase (most common) # keyfile - key stored locally, protected by passphrase (more secure) # none - no encryption (not recommended) # repokey-blake2 - repokey with BLAKE2b (faster) # authenticated - no encryption, but authenticated (integrity only)

Restic

sh
# Local repository restic init --repo /backup/restic-repo # SFTP repository restic init --repo sftp:backup@remote-server:/backup/restic-repo # S3 repository export AWS_ACCESS_KEY_ID="your-key" export AWS_SECRET_ACCESS_KEY="your-secret" restic init --repo s3:s3.amazonaws.com/my-backup-bucket # Backblaze B2 export B2_ACCOUNT_ID="your-id" export B2_ACCOUNT_KEY="your-key" restic init --repo b2:my-backup-bucket # REST server restic init --repo rest:https://backup:password@rest-server.example.com:8000/

Restic's backend diversity is its defining advantage. Native cloud storage support means no intermediate tools, no FUSE mounts, no workarounds.

Backup Workflow

BorgBackup

sh
# Create a backup export BORG_PASSPHRASE="your-passphrase" borg create --stats --progress --compression zstd,6 \ ssh://backup@remote-server/backup/borg-repo::'{hostname}-{now:%Y-%m-%d_%H:%M}' \ /etc \ /usr/local/etc \ /home \ /var/db/pkg \ /usr/local/www \ --exclude '*.cache' \ --exclude '/home/*/.cache' \ --exclude '*.pyc' \ --exclude '__pycache__' # Output shows dedup stats: # Original size: 2.45 GB # Compressed size: 1.12 GB # Deduplicated size: 45.23 MB <-- only new/changed data

Restic

sh
# Create a backup export RESTIC_PASSWORD="your-passphrase" export RESTIC_REPOSITORY="s3:s3.amazonaws.com/my-backup-bucket" restic backup \ /etc \ /usr/local/etc \ /home \ /var/db/pkg \ /usr/local/www \ --exclude-caches \ --exclude '*.pyc' \ --exclude '__pycache__' \ --tag freebsd-daily \ --verbose # Output shows snapshot ID and stats

Both tools automatically perform incremental backups. Only new or changed data is stored. Neither tool has a concept of "full" vs "incremental" -- every backup is effectively incremental, but every backup is also a complete, self-contained snapshot.

Deduplication Performance

Deduplication is where these tools earn their keep. We tested both on a typical FreeBSD server (10 GB of data, daily backups for 30 days, ~200 MB of daily changes):

| Metric | BorgBackup | Restic |

|---|---|---|

| First backup size (on disk) | 3.8 GB | 4.1 GB |

| After 30 daily backups (on disk) | 4.9 GB | 5.4 GB |

| Dedup ratio (30 days) | 61:1 | 56:1 |

| Chunk size (average) | ~128 KB (variable) | ~1 MB (content-defined) |

BorgBackup achieves slightly better deduplication due to its smaller average chunk size. Smaller chunks mean finer-grained deduplication -- if a single block in a file changes, only the affected chunks are stored again. Restic's larger chunks are faster to process but less granular.

The practical difference is small (10-15% in our tests). Both tools dramatically reduce storage compared to full backups.

Encryption

BorgBackup Encryption

Borg uses AES-256-CTR for encryption with HMAC-SHA256 for authentication. The key can be stored in the repository (repokey mode, protected by passphrase) or in a separate keyfile.

sh
# Export the key for safekeeping borg key export /backup/borg-repo /secure/borg-key-backup.txt # Change the passphrase borg key change-passphrase /backup/borg-repo

The repokey-blake2 mode uses BLAKE2b instead of SHA256 for HMAC, providing better performance on modern CPUs.

Restic Encryption

Restic uses AES-256-GCM (authenticated encryption with associated data). Every blob in the repository is encrypted with a unique key derived from a master key, which is protected by the repository password.

sh
# Change the repository password restic key passwd --repo /backup/restic-repo # Add an additional key (multiple users) restic key add --repo /backup/restic-repo # List all keys restic key list --repo /backup/restic-repo

Restic's use of AES-GCM (AEAD) is a more modern approach than Borg's AES-CTR + HMAC. Both are cryptographically sound.

Compression

BorgBackup Compression

Borg offers fine-grained compression control:

sh
# Use zstd at level 6 (good balance of speed and ratio) borg create --compression zstd,6 ... # Use lz4 for maximum speed borg create --compression lz4 ... # Disable compression for already-compressed data borg create --compression none ... # Auto-detect: try to compress, skip if data appears random/compressed borg create --compression auto,zstd,6 ...

Borg can also apply different compression based on file patterns:

sh
# In borgmatic config or Borg CLI # Compress text files aggressively, skip already-compressed files borg create --compression auto,zstd,12 \ --pattern '- *.jpg' \ --pattern '- *.mp4' \ --pattern '- *.gz' \ ...

Restic Compression

Restic added compression in version 0.14. It uses zstd with automatic detection:

sh
# Compression is enabled by default in new repositories restic init --repo /backup/restic-repo # Set compression mode restic backup --compression auto ... # default: compress if beneficial restic backup --compression max ... # maximum compression restic backup --compression off ... # no compression

Restic's compression is simpler -- no per-file patterns, no algorithm choice. For most use cases, the automatic mode works well.

Pruning and Retention

BorgBackup Pruning

sh
# Prune with retention policy borg prune --stats \ --keep-hourly=24 \ --keep-daily=7 \ --keep-weekly=4 \ --keep-monthly=12 \ --keep-yearly=3 \ ssh://backup@remote-server/backup/borg-repo # Compact to reclaim space (required after prune since Borg 1.2) borg compact ssh://backup@remote-server/backup/borg-repo

Borg separates pruning (marking archives for deletion) and compacting (actually freeing space). This two-step process is explicit and predictable.

Restic Pruning

sh
# Forget and prune in one step restic forget \ --keep-hourly 24 \ --keep-daily 7 \ --keep-weekly 4 \ --keep-monthly 12 \ --keep-yearly 3 \ --prune \ --repo s3:s3.amazonaws.com/my-backup-bucket # Or separate: forget (fast) then prune (slow) restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 restic prune

Important performance note: Restic's prune operation on cloud backends (S3, B2) can be slow because it needs to download, repack, and re-upload data packs that contain a mix of current and deleted data. For large repositories on cloud backends, prune can take hours. Borg's compact is generally faster because it operates on local or SSH-accessible storage.

Restore Workflows

BorgBackup Restore

sh
# List archives borg list ssh://backup@remote-server/backup/borg-repo # List files in a specific archive borg list ssh://backup@remote-server/backup/borg-repo::myhost-2026-04-09_02:00 # Extract an entire archive borg extract ssh://backup@remote-server/backup/borg-repo::myhost-2026-04-09_02:00 # Extract specific files borg extract ssh://backup@remote-server/backup/borg-repo::myhost-2026-04-09_02:00 \ etc/pf.conf usr/local/etc/nginx/nginx.conf # Mount and browse (FUSE) borg mount ssh://backup@remote-server/backup/borg-repo /mnt/borg # Browse /mnt/borg/myhost-2026-04-09_02:00/etc/... umount /mnt/borg

Restic Restore

sh
# List snapshots restic snapshots --repo s3:s3.amazonaws.com/my-backup-bucket # Restore latest snapshot restic restore latest --target /restore \ --repo s3:s3.amazonaws.com/my-backup-bucket # Restore specific files from a snapshot restic restore abc12345 --target /restore \ --include "/etc/pf.conf" \ --include "/usr/local/etc/nginx/" \ --repo s3:s3.amazonaws.com/my-backup-bucket # Mount and browse (FUSE) restic mount /mnt/restic \ --repo s3:s3.amazonaws.com/my-backup-bucket # Browse /mnt/restic/snapshots/latest/etc/... fusermount -u /mnt/restic

Both tools support FUSE mounting, which is extremely useful for restoring individual files without extracting the entire archive.

Append-Only Mode (Security)

Both tools support append-only mode to protect against ransomware or a compromised backup client deleting backups.

BorgBackup Append-Only

On the backup server, restrict the SSH key:

sh
# ~/.ssh/authorized_keys on backup server command="borg serve --restrict-to-path /backup/borg-repo --append-only" ssh-ed25519 AAAA... client-key

The client can create new archives but cannot delete or prune existing ones. Only the server administrator can prune.

Restic Append-Only

Using rest-server:

sh
# On the backup server pkg install restic-rest-server # Start rest-server in append-only mode rest-server --path /backup/restic-repos --append-only --private-repos

Performance Benchmarks on FreeBSD

Tested on FreeBSD 14.1, 4-core Xeon, 16 GB RAM, ZFS on NVMe. Backup target: 50 GB dataset, ~500K files.

| Operation | BorgBackup (SSH) | Restic (SSH/SFTP) | Restic (S3 local) |

|---|---|---|---|

| First backup | 12 min | 15 min | 18 min |

| Incremental (1% change) | 45 sec | 55 sec | 80 sec |

| Prune (30 archives) | 20 sec | 45 sec | 4 min |

| Full check | 8 min | 12 min | 25 min |

| Mount + file restore | 3 sec | 5 sec | 8 sec |

| Repository size (30 days) | 52 GB | 57 GB | 57 GB |

BorgBackup is consistently faster for SSH-based backups due to its optimized borg serve protocol. Restic is competitive for local and SFTP backups but slower on cloud backends due to API overhead.

Which to Choose

Choose BorgBackup if:

  • Your backup destination is a server you control (SSH).
  • You want the best deduplication ratio.
  • You use borgmatic for automated, well-structured backup management.
  • You need fine-grained compression control.
  • You want faster prune and check operations.

Choose Restic if:

  • You back up to cloud storage (S3, B2, Azure, GCS).
  • You want a single binary with zero dependencies.
  • You need cross-platform compatibility (same repo from FreeBSD, Linux, macOS).
  • You prefer a simpler tool with fewer options.
  • You want to avoid running special software on the backup server.

Consider Both if:

  • Use BorgBackup for your primary backup to a remote server (fast, efficient).
  • Use Restic for a secondary cloud backup (disaster recovery, geographic redundancy).
  • Two independent backup tools with different backends is robust defense in depth.

FAQ

Can BorgBackup back up directly to S3 or B2?

Not natively. Borg requires a POSIX filesystem or SSH access to the repository. You can use rclone to mount a cloud bucket as a FUSE filesystem and point Borg at it, but this is slower and less reliable than Restic's native cloud support. If cloud backends are important, use Restic.

Is Restic slower than BorgBackup?

For SSH-based backups, Borg is generally faster due to its optimized protocol (borg serve). For cloud backends, the comparison is moot because Borg does not natively support them. For local backups, they are comparable, with Borg having a slight edge in prune operations.

Can I migrate from BorgBackup to Restic or vice versa?

There is no direct migration tool. You would need to restore from one tool and back up into the other. Both use proprietary repository formats. The simplest migration is to keep the old repository for historical access and start fresh with the new tool.

How do I encrypt the backup passphrase in scripts?

On FreeBSD, store the passphrase in a file with restrictive permissions:

sh
# For BorgBackup echo "your-passphrase" > /root/.borg-passphrase chmod 600 /root/.borg-passphrase export BORG_PASSCOMMAND="cat /root/.borg-passphrase" # For Restic echo "your-passphrase" > /root/.restic-password chmod 600 /root/.restic-password export RESTIC_PASSWORD_FILE="/root/.restic-password"

For additional security, use a key management system or hardware security module.

Do Borg or Restic support backing up ZFS datasets?

Both tools operate at the file level, not the block level. They back up files within a ZFS dataset, not the dataset itself. For ZFS-level backups, use zfs send/receive. The best strategy is to use ZFS snapshots for local/replication backups and Borg or Restic for off-site file-level backups.

How much disk space do I need for the backup repository?

With deduplication, the repository size depends on:

  • Total data size (first backup)
  • Daily change rate
  • Number of retained snapshots
  • Compression ratio

A rough estimate: for 100 GB of data with 1% daily change and 30 daily snapshots, expect a repository size of 110-130 GB with either tool. Without deduplication, that same scenario would require 3 TB.

Get more FreeBSD guides

Weekly tutorials, security advisories, and package updates. No spam.