Borg is very good software. It does content-defined chunking, deduplicates across every archive in a repository, compresses, encrypts client-side with authenticated encryption, and has an append-only mode that is a genuinely strong answer to ransomware. If you are already running Borg and it is working, this article is not trying to talk you out of it.
The differences that matter are not the ones people expect. Both systems chunk, dedupe, encrypt on the client, and version snapshots. The real distinctions are operational, and there are three of them: who maintains the repository, how concurrency works, and what happens when the repo host is the thing that broke.
What Borg gets genuinely right
Worth saying clearly, because comparison pages usually skip it.
Append-only mode is excellent. Running borg serve --append-only on the repository host means a client can add archives and cannot remove them. A compromised backup client cannot destroy history. This is a real, well-designed implementation of the property that matters most for ransomware protection, and it predates most of the industry talking about immutability.
The encryption model is solid. Authenticated encryption, a key you hold, and repository access that reveals nothing to someone with only the storage.
Deduplication is repository-wide. Back up twenty similar servers into one repo and the shared content is stored once. For fleets of similar machines this is dramatically effective.
It is free, open source, and offline-capable. A Borg repo on a USB drive in a drawer is a legitimate air-gapped backup with no service dependency at all.
Where the operational cost lives
You run the repository. That means a host with disk, SSH, monitoring, capacity planning, OS patching, and its own backup story — because a Borg repository on a server nobody backs up is a single point of failure holding all your recovery options. For a team without existing infrastructure ops, this is the whole cost, and it does not show up in a feature comparison.
Repositories are single-writer. Borg locks the repository during operations. Multiple machines backing up concurrently to one repo will block or fail on the lock, and the standard advice is one repository per client — which throws away the cross-machine deduplication that made a shared repo attractive. Staggering cron schedules works until a backup runs long and collides with the next one.
Stale locks are a real failure mode. A client killed mid-backup leaves a lock behind, and the next run fails until someone runs borg break-lock. It is a one-line fix that requires a human to notice, which usually means noticing a week of silently failed backups.
Pruning needs care. borg prune with the wrong --keep-* combination deletes more than intended, and borg compact is what actually reclaims space. Both are safe when you understand them and unforgiving when you are guessing at 2am.
Side by side
| BorgBackup | Backup Data | |
|---|---|---|
| Deduplication | Content-defined, repo-wide | Content-defined (FastCDC), workspace-wide |
| Client-side encryption | Yes, authenticated | Yes, AES-256-GCM |
| Immutability | --append-only on the repo | Snapshots immutable; key scoped without delete |
| Concurrent clients | One writer per repo | Concurrent |
| Repository | You host and maintain it | Managed |
| Offline / air-gapped | Yes | No, needs network |
| Cost | Free + your server + your time | Free to 5 GB, then from $12/mo |
| Language / integration | CLI, Python | Node and Go SDKs, CLI |
| Restore verification | Integrity checked | Checksums verified before reassembly |
| Retention | borg prune + borg compact | pruneSnapshots with dry-run |
| Maturity | Long-established, large user base | Newer |
That last row is not a throwaway. Borg has been in production use for a decade across a very large number of installations. That is a real advantage and it should count for something in your decision.
Borg vs restic vs this
If you are comparing all three, the technical distinction between Borg and restic is smaller than either community's preferences suggest — both chunk, dedupe and encrypt well. The practical split:
- Borg — best-in-class dedupe ratios, append-only mode, but SSH-based and single-writer.
- restic — writes directly to object storage backends, handles concurrent clients better, no repo server to run. See our restic comparison.
- Backup Data — same guarantees, nothing to run at all, and the storage is not in your cloud account.
If your objection to Borg is "I don't want to run an SSH repo host," restic solves that without leaving self-hosting. If your objection is "I don't want to run anything," that is where a managed service is the answer.
The scenario worth thinking through
Ask where your Borg repository lives, and then ask what takes it out.
A repo on a second server in the same rack, or the same cloud account, dies with the same fire, the same compromised credentials, the same suspended account. Append-only mode protects against a compromised client; it does nothing about the repo host itself being lost, or someone with root on it.
A repo on a NAS in the office is fine until the office floods, or ransomware reaches a machine with the share mounted.
A repo at a Borg hosting provider (BorgBase, Hetzner Storage Box, rsync.net) is genuinely a good answer and worth knowing about — it removes the maintenance burden while keeping Borg. If you like Borg and want it managed, that is the natural path and it may well beat switching tools.
The remaining question is whether you want to keep operating Borg's model at all: the lock semantics, the prune-and-compact dance, per-client repos, and the client tooling on every machine.
Moving across
There is no migration path that transfers Borg archives, and pretending otherwise would be dishonest — the repository formats are unrelated. What you do instead is run both for a retention period, then retire the old one.
# Whatever your borg script already assembles, keep doing.
pg_dump --format=custom --file=./staging/db/app.dump app_db
import { BackupClient } from "@lighthouse-web3/baas-js-sdk";
const client = new BackupClient({
apiKey: process.env.LH_API_KEY, // write + read scopes only
workspaceId: process.env.LH_WORKSPACE_ID,
});
await client.backup(["./staging"], {
description: "nightly",
tags: { type: "db-backup", host: "db-01" },
encryption: {
keyfilePath: "/secure/lh.keyfile",
passphrase: process.env.LH_KEYFILE_PASSPHRASE,
},
});
Two habits transfer directly, and both are good ones:
You still hold the keys. Same model, same consequence — lose the keyfile and passphrase and the data is unrecoverable, with no server-side reset. If you already treat your Borg keyfile as a root credential, keep doing exactly that.
Append-only becomes a scoped key. Where you would run borg serve --append-only, mint an API key with write and read scopes and nothing that permits deletion, and run pruning from somewhere else entirely. Same separation of powers, different mechanism.
The honest summary
Stay with Borg if: you already run it successfully, you need offline or air-gapped repositories, you back up many similar machines and repo-wide dedupe is saving you real money, or you specifically want tooling you can audit and self-host. These are good reasons and there is no cleverness that overrides them.
Look at this instead if: you do not want to maintain a repo host, the single-writer lock is causing you scheduling pain, you want backups outside your own infrastructure entirely, or you want an SDK rather than shelling out to a CLI from your application.
Borg is not the wrong choice. For a team with infrastructure people and a clear place to put the repository, it may well be the better one. The question this comparison is really asking is whether running that repository is work you want to keep doing.
Start with the free tier: backupdata.io has 5 GB free, no card, and the 10-minute quickstart gets you to a first verified snapshot today.