restic vs Borg: Choosing a Backup Tool

restic vs Borg: Choosing a Backup Tool

Both tools do the same core things: chunk files, deduplicate, compress, encrypt, and store snapshots. Both are mature and widely used. The choice comes down to where the backups go and how you operate them.

Our backup guide covers the wider discipline, and this compares the two tools directly.

What they share

Content-defined chunking. Files are split at boundaries determined by a rolling hash of the content rather than at fixed offsets. That matters because inserting a byte at the start of a file shifts everything after it, and with fixed-size chunks every subsequent chunk would change. With content-defined boundaries, the chunks after the insertion are identical and are not re-stored.

Deduplication across everything. A chunk appearing in a hundred files, or in a hundred snapshots, is stored once. Backing up twenty similar servers to one repository stores the shared system files once.

Encryption before transmission. The repository server never sees plaintext, which means untrusted storage is acceptable.

Snapshots, not incrementals. Every snapshot is a complete view. There is no full-versus-incremental distinction and no chain to restore through.

restic

export RESTIC_REPOSITORY="s3:s3.amazonaws.com/my-backups"
export RESTIC_PASSWORD_FILE="/root/.restic-password"

restic init
restic backup /home /etc /srv --exclude-file=/root/backup-excludes
restic snapshots
restic restore latest --target /tmp/restore
restic restore latest --target / --include /etc/nginx

The distinguishing feature is backend support. restic talks natively to local paths, SFTP, S3 and every S3-compatible service, Backblaze B2, Azure, Google Cloud Storage, and anything rclone supports.

Crucially, nothing needs to be installed at the destination. Object storage works directly, which means cheap providers like Backblaze B2 or Wasabi are usable with no server to maintain.

It is a single static Go binary. Copy it to a machine and it works, with no dependencies to install.

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
restic check
restic check --read-data-subset=5%

Borg

export BORG_REPO="ssh://backup@server/./repo"
export BORG_PASSPHRASE_FILE="/root/.borg-passphrase"

borg init --encryption=repokey-blake2
borg create --stats --compression zstd,3 ::'{hostname}-{now}' /home /etc /srv
borg list
borg extract ::archive-name
borg mount ::archive-name /mnt/restore

Borg is generally faster and more space-efficient, particularly on the initial backup and on repositories with many archives. Its chunk index is more compact and its compression options are better, with zstd at selectable levels and lzma for maximum density.

borg mount is a genuinely useful feature: it exposes an archive as a FUSE filesystem, so you browse it with ls and cp rather than extracting first. restic has restic mount as well and Borg’s has been around longer and is more polished.

The constraint: efficient remote operation requires Borg on the remote host. It runs a server process over SSH. You cannot point Borg at S3 and have it work well, which rules out plain object storage without an intermediary like rclone, and that loses much of the efficiency.

borg prune --keep-daily=7 --keep-weekly=4 --keep-monthly=12
borg compact
borg check --verify-data

Note borg compact as a separate step. prune removes references; compact reclaims the space.

The differences that decide it

resticBorg
Object storageNativeNeeds rclone, poorly
Remote requirementNoneBorg on the server
SpeedGoodBetter
Space efficiencyGoodBetter
Multiple clients per repoSupportedNot recommended
InstallationOne binaryPython, packaged
Compressionzstdzstd, lzma, more levels

The multiple-clients question matters operationally. restic handles concurrent access to one repository with locking, so twenty servers can share a repository and deduplicate against each other. Borg’s cache assumes a single writer, and concurrent access risks corruption, so you run one repository per machine and lose cross-machine deduplication.

If you are backing up a fleet of similar servers, that difference is large.

Retention

Both express the same idea:

restic forget \
  --keep-last 3 \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 12 \
  --keep-yearly 3 \
  --prune

borg prune \
  --keep-last 3 \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 12 \
  --keep-yearly 3
borg compact

Run the prune step. A repository that grows despite a retention policy is almost always one where forget runs without --prune, or borg prune runs without borg compact.

Append-only mode

The feature that matters for ransomware.

A compromised machine with full repository access can delete every backup, which is exactly what modern ransomware does before encrypting.

Both tools support restricting a client to appending:

# Borg, in the server's authorized_keys
command="borg serve --append-only --restrict-to-path /backups",restrict ssh-ed25519 AAAA...
# restic, with an S3 bucket policy denying DeleteObject to the backup key

The client writes new snapshots and cannot remove old ones. Pruning is done separately, from the repository server or with a different key.

This is not complete protection, since an attacker who reaches the repository server itself can still delete. It defeats the common case, which is a compromised client.

Object storage with versioning and object lock is stronger still, because the provider enforces immutability for a set period regardless of credentials.

Automating

# /etc/systemd/system/backup.service
[Unit]
Description=Backup

[Service]
Type=oneshot
EnvironmentFile=/root/.backup-env
ExecStart=/usr/local/bin/restic backup /home /etc /srv --exclude-file=/root/excludes
ExecStart=/usr/local/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
Nice=19
IOSchedulingClass=idle
# /etc/systemd/system/backup.timer
[Timer]
OnCalendar=daily
RandomizedDelaySec=1h
Persistent=true

[Install]
WantedBy=timers.target

Persistent=true runs a missed backup after the machine comes back up, which is what you want on a laptop. RandomizedDelaySec spreads load if several machines target one repository. Our systemd timer builder generates these.

Nice=19 and IOSchedulingClass=idle keep the backup from interfering with real work.

Monitor it. A backup job that has been failing silently for three months is the standard disaster:

ExecStart=/usr/bin/curl -fsS https://hc-ping.com/YOUR-UUID

Healthchecks.io or a self-hosted equivalent alerts you when a job stops reporting, which is the failure mode that matters, since a job that never runs generates no error.

Restore testing

The step that makes the difference between a backup and a belief.

restic restore latest --target /tmp/restore-test --include /etc/nginx
diff -r /etc/nginx /tmp/restore-test/etc/nginx

borg extract --dry-run --list ::archive-name
borg mount ::archive-name /mnt/check && ls /mnt/check

Do this monthly and put it in the calendar. Our self-hosting guide makes the same point at more length, because it is the single most common way people lose data despite having backups.

Picking

restic if backups go to object storage, if several machines share a repository, or if you want one binary with no server-side component. This covers most people.

Borg if backups go to a server you control, if the dataset is large enough that its efficiency advantage is worth real money, or if you want its compression options.

Either is a substantial improvement on rsync snapshots or on nothing. The tool matters less than having one, running it automatically, monitoring it, and testing restores.

Frequently Asked Questions

What is the main difference between restic and Borg?

restic is a single Go binary that talks natively to many backends including S3, Backblaze B2, and other object storage. Borg is faster and more space-efficient but needs Borg installed on the remote host for efficient operation, which limits it to servers you control rather than plain object storage.

Can two machines back up to the same repository?

With restic yes, since it handles concurrent access with locking. Borg strongly recommends one repository per machine because its cache assumes a single writer, and concurrent access can corrupt the repository. Use separate Borg repositories per client.

How does deduplication work in these tools?

Both split files into variable-sized chunks using content-defined boundaries, hash each chunk, and store only chunks they have not seen before. Because the boundaries follow content rather than fixed offsets, inserting data at the start of a file does not change the chunks after it.

Do I need to run prune to reclaim space?

Yes. Deleting or forgetting snapshots removes the references, and the underlying data is only removed when you prune. A repository that grows despite a retention policy is nearly always one where forget is being run without prune.

Can I trust append-only mode to protect against ransomware?

It helps substantially. Both tools support restricting a client key to appending only, so a compromised machine can write new backups but cannot delete old ones. It is not complete protection, since an attacker with access to the repository server itself can still remove data.

Which is faster for large backups?

Borg, generally, particularly for the initial backup and for repositories with many snapshots, because its chunk index is more compact and its compression options are stronger. restic has improved considerably and the gap matters most at the scale of terabytes rather than gigabytes.