Head to head
restic vs BorgBackup
Both encrypt, deduplicate and are boringly reliable. The choice comes down to where the repository lives and what happens the day Borg 2 finally ships.
Should you use restic or BorgBackup?
Use restic unless every backup destination you will ever have is an SSH host you control, in which case BorgBackup is slightly better at that one job. The deciding fact is portability of destination: restic writes straight to S3, Backblaze B2, SFTP or any rclone remote with nothing installed on the other side, while Borg requires a matching Borg binary at both ends. Borg is also mid-transition: 1.4.5 is the stable series, 2.0 has been in beta for years (2.0.0b24 on 2 September 2026), and moving between them is a full repository rewrite, not an upgrade.
The feature lists are nearly identical: encrypted, deduplicated, compressed snapshots driven from cron, no daemon, no web UI, both started in 2015, both still going. Comparing checkboxes tells you nothing. The decision is actually two questions. Where is the repository allowed to live, and which project's next major version is going to cost you a weekend?
What the specification table decides#
Read three rows and ignore the rest. Datastore tells you that neither one has a database service to run or a schema to migrate, so day-two operations are cron and disk space, not upgrades. Idle memory is misleading for both, because neither has a daemon: those are figures during a run, and the number that matters is the peak during pruning, which is discussed below. arm64 builds is the row people skip and then regret.
| Specification | restic | BorgBackup |
|---|---|---|
| Licence | BSD-2-Clause (Permissive) | BSD-3-Clause (Permissive) |
| Written in | Go | Python / C / Cython |
| First release | 2015 | 2015 |
| Maturity | Mature | Mature |
| Datastore | Its own content-addressed repository (files in a directory or bucket), no database service | Its own repository format, plus a local chunks index and files cache under ~/.cache/borg |
| Services to run | not container shaped | not container shaped |
| Idle memory | 100 MB | 80 MB |
| Memory in use | 800 MB | 400 MB |
| Operational load | 2 / 5, Light | 2 / 5, Light |
| Identity | Not applicable | Not applicable |
| arm64 builds | Yes | No |
| Default ports | none | none |
| Backup shape | Mixed | Mixed |
Borg 2 has not shipped, and that changes the recommendation#
As of September 2026 the stable Borg series is 1.4, at 1.4.5 released 19 July 2026. Borg 2.0 is still beta: 2.0.0b24 landed on 2 September 2026 and the project's own release page describes the series as testing, for new repositories, not for production. If you read an article from 2023 saying 2.0 was around the corner, it was wrong then and it is still wrong.
That would be a footnote if 2.0 were an ordinary upgrade. It is not. Repositories are incompatible between 1.x and 2.x, so there is no in-place migration. You run:
borg2 repo-create --other-repo ssh://borg@nas/srv/borg/web1 --encryption repokey-blake2
borg2 transfer --other-repo ssh://borg@nas/srv/borg/web1 --upgrader=From12To20That rewrites every archive from the old repository into a new one. It needs free space for a second copy of your data, a maintenance window proportional to total size rather than to daily change, and the source repository has to be on 1.2.6 or later with the manifest and archive TAM upgrade already applied. On a 3 TB repository over a home uplink that is not an evening, it is a project.
The honest read: starting Borg today means starting on 1.4 and accepting that at some future point you owe yourself a full repository rewrite. That is a real cost that restic does not charge you, and it is the strongest single argument in this comparison.
restic's repository format v2 and what compression cost the people who already had a repo#
restic 0.19.1 (5 July 2026) is still a 0.x version after eleven years, which bothers people more than it should. The format story is cleaner than Borg's. Compression arrived in 0.14 alongside repository format 2, and format 2 is what restic init creates today with --compression auto as the default.
The catch is only for existing repositories, and it is worth stating precisely because it is the mirror image of the Borg 2 problem at a tenth of the size:
restic migrate upgrade_repo_v2 # flips the format, compresses nothing
restic prune --repack-uncompressed # rewrites every pack fileThe first command is instant and does nothing to your data: new backups get compressed, existing pack files stay uncompressed, and your repository size does not move for months. The second command is the one that actually converts, and it downloads and re-uploads the entire repository. On a remote bucket that is a genuine egress bill. Schedule it deliberately rather than discovering it.
Difference in kind: restic's rewrite is optional and gets you smaller storage. Borg's rewrite is mandatory and gets you the next major version.
Where the repository is allowed to live#
This is the structural difference and it does not change with releases.
Borg speaks its own protocol. The client runs borg, the repository host runs borg serve, and the versions have to match closely or you get protocol complaints. That means you need shell access and a Borg binary on the far end. A Backblaze B2 bucket cannot run borg serve. Neither can an S3 endpoint, a Hetzner Storage Box in its S3 mode, or a friend's NAS that only exposes SMB.
restic compiles its backends in: local path, SFTP, REST, S3, Azure, Google Cloud Storage, B2, and anything rclone reaches via the rclone: prefix. Initializing a repository on object storage is one command with no server side at all:
export RESTIC_REPOSITORY="s3:s3.us-west-004.backblazeb2.com/tdg-backups/web1"
export RESTIC_PASSWORD_FILE=/etc/restic/pass
restic init
restic backup /srv /etc --exclude-caches --compression autoBorg's equivalent needs an account on the destination:
borg init --encryption=repokey-blake2 borg@nas:/srv/borg/web1
borg create --compression zstd,3 borg@nas:/srv/borg/web1::web1-{now} /srv /etcIf you already have that SSH account, Borg's version is arguably nicer: strongly consistent, single writer, no eventual consistency to reason about, and the tool is in your distro repository so the package manager patches it. If you do not, restic saves you from standing up and maintaining a host whose entire job is to hold backups. Pair restic with Garage or a rented bucket and you are done. See MinIO vs Garage before you decide to run your own S3 endpoint for this, because for a single restic client you probably should not.
Append-only: both can do it, neither does it by itself#
The scenario is a compromised backup client running restic forget --keep-last 0 or borg delete. Encryption does not help. Only server-side enforcement does.
Borg's version lives in authorized_keys on the repository host:
command="borg serve --append-only --restrict-to-path /srv/borg/web1",restrict ssh-ed25519 AAAAC3Nza... web1That client can now write archives and read them and nothing else. The catch already mentioned: borg compact needs write access, so it has to run from a separate privileged session on the repository host, usually a local cron job.
restic has two versions. Run rest-server (port 8000) with --append-only, which is the direct analogue and needs a machine. Or use a bucket with S3 Object Lock in compliance mode, which needs no machine and cannot be undone by anyone including you. The second option is genuinely stronger than anything Borg offers, because the enforcement survives the loss of the whole server.
Verdict on this section: Borg is easier to set up append-only, restic can be made harder to defeat. Both are covered in more depth in Backups that actually restore.
Pruning is where the difference bites small hardware#
Neither tool reclaims space when you delete snapshots. Both need a second step, and both steps are where operators get hurt.
restic holds the repository index in RAM, and prune is the peak. A few hundred GB of repository is comfortable in under 1 GB. Multi-terabyte repositories with tens of millions of blobs want several GB and get OOM-killed on a small VPS, halfway through, leaving a lock behind. Mitigations, in order of effectiveness:
restic forget --host web1 --keep-daily 7 --keep-weekly 4 --keep-monthly 12
restic prune --max-repack-size 20G --retry-lock 10mRun forget often so the pruned set stays small, bound the work per run with --max-repack-size, and prune from a machine with real memory rather than from the Pi being backed up. --retry-lock arrived in 0.16.0 and is the fix for the other failure mode: a killed run leaves an exclusive lock and the next run refuses to start.
Borg publishes an actual formula instead of a shrug: chunk_count * 164 + total_file_count * 240 bytes, and the manual's worked example of one million files across 1 TB comes to 0.31 GiB. It is predictable in a way restic is not, and on constrained hardware that predictability is worth something. Borg's cost lands elsewhere: the chunks index and files cache under ~/.cache/borg are keyed to the repository, and a second machine touching the same repository triggers a full cache resync that reads a large amount of metadata over your link. Give each client its own repository.
The Borg maintenance loop that people get wrong:
borg prune --glob-archives 'web1-*' --keep-daily 7 --keep-weekly 4 --keep-monthly 12
borg compactTwo traps in two lines. Without --glob-archives, prune applies your retention rules to every archive in the repository, including another host's. Without compact, nothing is freed. restic's forget has the identical scoping trap and the identical fix (--host or --tag), so do not read this as a Borg-specific flaw.
Which one for your situation#
| Your situation | Use | Why |
|---|---|---|
| Backing up a VPS or NAS to B2, S3 or Wasabi | restic | Nothing to install at the far end, and Object Lock gives you real immutability |
| You already have SSH to a box with disks | BorgBackup | borg serve --append-only is fifteen minutes of work and gives you a single-writer, strongly consistent repository |
| Mixed fleet with ARM boards | restic | Official arm64 binaries; Borg's standalone builds are x86-64 only |
| Several machines into one destination | restic | Borg locks a repository exclusively so clients queue, and cross-machine cache resync is slow |
| Repository will exceed 2 TB and the backup host has 2 GB RAM | BorgBackup | Documented memory formula beats restic's index-in-RAM pruning |
| Debian or RHEL fleet patched by the package manager | BorgBackup | It is in the distro; restic is a binary you update yourself |
| Starting fresh in 2026 with no constraints | restic | You do not inherit a mandatory repository rewrite |
What to do next#
Pick one, then rehearse the restore before you trust either. Run Backup planner to size the repository and the retention policy against what you are actually backing up, then read Backups that actually restore for the verification cadence (restic check --read-data-subset=1/10 or borg check --verify-data monthly, not annually). If a database is in the backup set, Backing up a running database matters more than which of these two you chose, because a consistent dump beats a clever deduplicator.
If neither appeals because you want a GUI or a schedule you can click, read restic vs Kopia and Duplicati vs restic next. The full Backup category has the profiles for Kopia, Duplicati and rclone, and The backup blind spot has the data on which self-hosted apps cannot be backed up by file copy at all.
Questions#
Is BorgBackup dead because Borg 2 is taking so long?
No. The 1.4 series is actively maintained and 1.4.5 shipped on 19 July 2026. What has stalled is the 2.0 release, which has been in beta long enough that articles written in 2023 promising an imminent 2.0 are still wrong. If you run Borg today you run 1.4, you get bug fixes, and you plan the 2.0 transition as a data migration whenever it lands rather than as a package upgrade.
Can restic back up to a Borg repository or the other way round?
No. The two repository formats are unrelated and there is no converter. Switching tools means starting a new repository and keeping the old one read-only until its retention window expires. Budget for both existing at once: for a 500 GB source that is roughly a second full copy of your deduplicated data, plus the time to seed it.
Which one is safer against ransomware?
Both can be made append-only, and both need the server side to enforce it. For Borg you force the command in authorized_keys to borg serve --append-only --restrict-to-path /srv/borg/host1. For restic you either run rest-server with --append-only or point it at a bucket with S3 Object Lock. Borg's version is easier to set up on a box you already SSH into; restic's version survives the loss of that box because the enforcement lives in the storage provider.
How much RAM does pruning actually need?
restic loads the whole repository index into memory and prune is the peak, so multi-terabyte repositories with tens of millions of blobs want several GB and get OOM-killed on a 2 GB VPS. Borg publishes a formula: chunk_count 164 + total_file_count 240 bytes, and its own worked example of one million files across 1 TB comes to 0.31 GiB. Borg is the more predictable one here, and the difference is real on small hardware.
Do I still need `borg compact` if I run `borg prune`?
Yes, and forgetting it is the single most common Borg misconfiguration. Since 1.2, prune only removes archive references; disk space returns when borg compact rewrites segment files. A cron job with create and prune but no compact grows forever and looks like broken deduplication. Note that compact needs write access, so it cannot run against an append-only repository and has to be run separately on the repository host.
Does restic support arm64 and does Borg?
restic ships official arm64 binaries and multi-arch images, so a Raspberry Pi or an ARM VPS is a first-class target. Borg publishes standalone PyInstaller binaries for x86-64 only; on ARM you use the distro package or pip, and the ARM binaries linked from the docs are built by a third party. If half your fleet is ARM, that asymmetry is worth more than any feature difference.
Sources#
- Borg release series page, 1.4.5 stable and 2.0 in testing
- Borg GitHub releases, 2.0.0b24
- Borg changelog and upgrade notes for 1.4 and 2.x
- Borg internals, index and cache memory formula
- Borg installation, official binaries and packages
- restic 0.19.1 release announcement
- restic docs, preparing a new repository and repository versions
- restic docs, working with repositories (upgrade_repo_v2, repack-uncompressed)
- restic 0.16.0 release notes, --retry-lock
Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.