The short answer
Pick restic if you want the safe default: it was the fastest or close to it in every test, it restores quickly, it is in Debian, and with its REST server in append-only mode a hacked server cannot delete its own backups. That is the setup in our restic guide. Pick Borg if your backup storage is a server or storage box you reach over SSH and you value a long track record: it stored the same data in the same space, but took twice as long per backup on our two cores, and cannot write to S3 until Borg 2 is out of beta. Pick Kopia if you want a graphical interface, retention and scheduling built into one command, or object locks on S3 storage, and can live with more memory, a larger cache and much slower restores in our test.
All three deduplicate, compress and encrypt on the server you back up, so the place that stores your backups never sees your files. The differences are in speed, in how they protect old backups, and in how much you have to set up yourself.
What we tested
We installed all three on one Melonslab VC-P Alloy (2 vCPU, 8 GB) with Debian 13:
- restic 0.18.0 and rest-server 0.13.0 from Debian, following our restic guide for the REST server in append-only mode, with a certificate and a password per server.
- Borg (BorgBackup) 1.4.0 from Debian, with
apt install borgbackup. - Kopia 0.23.1 from Kopia's own apt repository, as described in its installation docs. Kopia is not in Debian.
Each tool backed up the same folder, 3.46 GB in 86,623 files: the Linux 6.12 source code (86,600 small files, 1.6 GB), three 400 MB files of random data standing in for videos or photos, a 300 MB web server log, and a 390 MB pg_dump of a PostgreSQL database. Then we changed about 5 % of it: a new 100 MB file, 15 MB more log, 3,000 edited source files, a deleted folder and 3,000 new small files, 175 MB of new data in all. Then we ran an hour's worth of writes against the database, dumped it again, and backed up once more.
The backups went to two kinds of storage:
- Over SSH, to a second user on the same server with an SSH key, as you would with a backup server or a storage box: SFTP for restic and Kopia, and
borg servefor Borg. restic also went to its REST server. - S3, to Garage on the same server, through Caddy with HTTPS. Borg 1.4 cannot write to S3, so this was restic and Kopia only.
Since the storage was on the same server, the network played no part: the times show what each tool does with two CPU cores and an SSD. Before every run we emptied the page cache, so each tool read the files from disk, as in a nightly backup. We used zstd compression at level 3 in all three, so that the sizes compare the same thing, and measured Borg's default lz4 once too. Every full restore was compared file by file against checksums of the originals, and all matched.
The numbers
Over SSH, the setup most people will use:
| restic | Borg | Kopia | |
|---|---|---|---|
| First backup, 3.46 GB | 2 min 29 s and 2 min 35 s | 5 min 25 s and 5 min 9 s | 2 min 36 s and 3 min 24 s |
| Next backup, 175 MB new | 26 s | 1 min 10 s | 29 s |
| Backup with nothing changed | 12 to 14 s | 47 s | 8 to 13 s |
| New database dump, 390 MB | 38 s | 56 s | 14 s |
| Repository after four backups | 1,695 MiB | 1,681 MiB | 1,691 MiB |
| Peak memory during a backup | 133 to 141 MB | 152 MB, plus 81 to 104 MB on the backup server | 434 to 447 MB |
| Restore everything | 1 min 32 s | 1 min 38 s and 1 min 42 s | 5 min 15 s |
| Restore one small file | 3 s | 6 s | 4 s |
| Restore the 390 MB dump | 5 s | 7 s | 8 s |
| Quick check | 8 s | 27 s | 6 s |
| Check that reads all data | 54 s | 1 min 44 s | 6 min 27 s |
| Remove old backups, keeping 1 of 4 | 7 s | 8 s, and 2 s to free the space | 5 s, and 10 to 23 s to free the space |
| Local cache on the server you back up | 34 MB | 14 to 29 MB | 114 MB, and 2.4 GB after restores |
Where there are two figures, we ran the test twice, once more in a fresh repository. The second backup's 175 MB took about 141 MB in both restic and Borg once compressed. The new database dump differed little from the old one, and took 5 MiB in restic and 4.5 MB in Borg.
To S3 storage, and to restic's REST server:
| restic, REST server | restic, S3 | Kopia, S3 | |
|---|---|---|---|
| First backup | 3 min 24 s | 2 min 42 s | 3 min 15 s |
| Next backup, 175 MB new | 23 s | 25 s | 29 s |
| Peak memory during the first backup | 136 MB, and 22 MB for the REST server | 252 MB | 411 MB |
| Restore everything | 1 min 11 s | 1 min 8 s | 14 min 14 s |
Installing took seconds for each: apt install for restic and Borg, and adding Kopia's signing key and repository first. The steps in the restic guide, including the REST server and its certificate, took 13 seconds to run.
Setup
restic is one program, in Debian. It speaks SFTP, S3 and S3-compatible storage, Backblaze B2, Azure, Google Cloud Storage, its own REST server, and anything rclone can reach. You point it at a repository with an address and a password file, and restic init creates it. Debian 13 has 0.18.0, while the latest release is 0.19.1 from July 2026: what is in the restic guide works with Debian's version.
Borg is also in Debian, written in Python with the heavy parts in C. Over SSH it needs Borg installed on the backup server too, because the client talks to borg serve on the other end, not to plain SFTP. That is also what makes its append-only mode possible. Storage boxes sold for backups often support Borg for this reason. Borg 1.4 reaches only local folders and SSH: no S3. Borg 2, which adds SFTP, S3, B2 and rclone, has been in beta for a long time, at 2.0.0b25 in September 2026, and uses a new repository format that Borg 1 cannot read.
Kopia is one program, plus an optional desktop app, KopiaUI, and a web interface in its server mode. It reaches the same kinds of storage as restic, minus the REST server. It is not in Debian: you add Kopia's apt repository, or download a release from GitHub. A new repository has no compression until you set a policy, so add kopia policy set --global --compression=zstd. It also comes with a retention policy already switched on, which deletes snapshots by itself (see below). The Kopia command line checks GitHub once a day for a newer version, unless you set KOPIA_CHECK_FOR_UPDATES=false. restic and Borg made no connections of their own.
Speed and memory
Borg 1.4 chunks, compresses and encrypts in a single thread: during its first backup it used 65 % of one core on average, where restic used 133 %. On our two-core server that made Borg the slowest at backing up, about twice as long as the other two for a first backup and for the backup after the change. Even with nothing changed, Borg took 47 seconds, against 8 to 14 for the others: it spent most of that time in its own code, loading its cache and writing the list of 88,000 files. With Borg's default lz4 compression instead of zstd, its first backup took 4 minutes 18 seconds, and its repository grew to 1,886 MiB instead of 1,664.
Kopia was the fastest with the new database dump, 14 seconds against 38 for restic, and the slowest to restore. A full restore took 5 minutes 15 seconds over SFTP, three times as long as restic, and 14 minutes from Garage. Kopia fetches each stored piece on its own, and this data set had about 100,000 of them, where restic fetched whole pack files. During Kopia's restore from S3, Garage used most of a CPU core to serve the reads. With 32 parallel workers instead of the default 8, it still took 13 minutes. Storage that handles small reads better than one Garage on a two-core server would narrow the gap, but we did not test that. Kopia also kept a copy of everything it restored in its cache, 2.4 GB here: its default limit is 5 GB.
Memory was close between restic and Borg, around 140 to 150 MB while backing up, though Borg also needs 80 to 100 MB for borg serve on the backup server. restic used 250 MB writing to S3. Kopia used 400 to 450 MB. None of them runs anything between backups, except the restic REST server, which peaked at 22 MB, and Kopia's server if you choose to run it.
Removing old backups
All three remove old snapshots by a rule, such as "keep 7 daily, 4 weekly and 6 monthly", and then free the space that only those snapshots used.
restic does both with restic forget --prune. Keeping 1 of 4 snapshots took 7 seconds over SFTP. With the REST server in append-only mode, the server you back up cannot do it: in the restic guide, the backup server prunes the repository itself, and needs the repository's password for that. Since restic 0.18, a rule also keeps the oldest snapshot while there are fewer than the rule asks for, so with backups from a single day our server kept two.
Borg splits it in two: borg prune removes archives, 8 seconds, and borg compact frees the space, 2 seconds here. compact needs no key, so it can run on the backup server without the password.
Kopia applies its retention policy by itself after each snapshot. The default keeps the latest 10, plus 48 hourly, 7 daily, 4 weekly, 24 monthly and 3 annual snapshots. Space is freed by maintenance, which Kopia also runs by itself: a quick cycle every hour and a full one every day, from the user and host that created the repository. Full maintenance only removes data that has been unused for a while, as a safety margin: right after we removed three snapshots, it found 17 MB unused, called it too recent, and kept it. With --safety=none it removed it in 23 seconds.
Checking the backups
restic checkreads the repository's index and the list of every snapshot, file and folder, and checks that all the data they point to is there. It took 8 seconds.restic check --read-dataalso downloads and decrypts every piece and checks its hash, 54 seconds.--read-data-subset 10%reads a tenth at a time, as the restic guide does monthly.borg checkchecks the repository on the backup server, every segment against its checksum, without the key, and then the archives with the key. It took 27 seconds.--verify-dataalso decrypts every piece and checks its authentication code, 1 minute 44 seconds.kopia snapshot verifychecks that every file and folder in the snapshots points to data that exists, in 6 seconds. With--verify-files-percent=100it also reads and decrypts every file, which took 6 minutes 27 seconds, for the same reason that its restores are slow.
All found no errors.
Encryption
All three encrypt on the server you back up, before anything leaves it, and authenticate what they read back, so a changed or damaged piece is noticed. None stores a copy of your password: lose it, and the backups are lost too.
- restic derives a key from your password with scrypt. The parameters are tuned when you create the repository: ours were N=32768, r=8, p=2. That key unlocks a random master key, which encrypts all data with AES-256 in CTR mode and authenticates it with Poly1305-AES. Snapshots, file names and folders are all encrypted. The storage can see the size and number of pack files and when they were written, and each key file shows in plain text the user name and host name that created it.
- Borg 1.4 derives the key that unlocks its keys with PBKDF2-HMAC-SHA256, 100,000 iterations, which is weaker against password guessing than scrypt. Data is encrypted with AES-256 in CTR mode and authenticated with HMAC-SHA256, or with BLAKE2b in the
-blake2modes, faster on processors without SHA instructions such as ours. Withrepokeythe encrypted key is stored in the repository, and withkeyfileonly on your server, so a password alone is not enough. Borg's documentation says it does not hide the size of the pieces it stores, and that it cannot keep data confidential when several servers write to the same repository. Borg 2 changes to modern authenticated encryption and Argon2. - Kopia derives the key with scrypt (N=65536, r=8, p=1), and encrypts with AES-256-GCM by default, or ChaCha20-Poly1305. Snapshots, file names and folders are encrypted, and stored blobs are named after hashes. The repository's format file shows in plain text the Kopia version that created it, its unique ID and the key settings.
Protection against a hacked server
A backup that the server can delete is no protection if someone takes over that server, or ransomware encrypts it. Each tool has a way to let a server add backups but not remove them, and we tried to delete backups through each:
- restic with rest-server
--append-only, as in the restic guide:restic forgetfailed with403 Forbidden, and every snapshot was still there. The output in between looks as if snapshots were removed, and restic 0.18.0 exited with status 0, so checkrestic snapshotsrather than the exit code. - Borg with
borg serveforced in the backup server'sauthorized_keys, for the key of the server you back up:command="borg serve --restrict-to-repository /home/borg/web1 --append-only",restrict ssh-ed25519 AAAA... root@web1borg pruneseemed to work, andborg listshowed one archive instead of four. Nothing was deleted on disk, though. Following Borg's documentation, we removed the newest transaction's files on the backup server, cleared the client's cache, and all four archives were back. This works only until someone runsborg compactin normal mode, which makes the deletions permanent, so check before you compact. The next backup took longer, because Borg rebuilt its cache. - Kopia with its repository server, where clients connect to Kopia on the backup server rather than to the storage directly. By default a client may delete its own snapshots. We changed that rule to
APPENDwithkopia server acl, andkopia snapshot deletethen failed withaccess denied, and the snapshots stayed. The server holds the repository's password and runs maintenance. Kopia can also put object locks on S3, Azure and Google Cloud storage, so that nothing can be deleted until a date, even with the storage's keys. Garage does not support object locks, so we did not test that.
restic has no object-lock support of its own, and Borg 1.4 cannot use S3 at all. In all three setups, someone who takes over the backup server itself can still delete everything there, so keep that server's login separate from the servers it backs up.
Running every night
None of the three needs a daemon on the server you back up: a systemd timer starting a service once a night works for each. The restic guide has the full setup, with a warning at login when a backup fails. For Borg and Kopia we used the same timer, OnCalendar=*-*-* 02:00 with RandomizedDelaySec=1h and Persistent=true, and these services, which ran and finished without errors.
Borg, with the passphrase in /etc/borg/passphrase (chmod 600) and the backup server's address in place of backup.example.com:
[Unit]
Description=Back up this server with Borg
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
Environment=BORG_REPO=ssh://borg@backup.example.com/home/borg/web1
Environment="BORG_PASSCOMMAND=cat /etc/borg/passphrase"
Nice=10
IOSchedulingClass=idle
ExecStart=/usr/bin/borg create --compression zstd,3 --exclude-caches ::{hostname}-{now} /etc /home /srv
ExecStartPost=/usr/bin/borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --glob-archives {hostname}-*
Kopia stores the repository's password next to its configuration after kopia repository create or connect, readable by root only, so the service needs no secret of its own. It does need the path to that configuration: a system service has no home folder set, and Kopia then reports repository is not connected. Retention and maintenance run as part of the snapshot:
[Unit]
Description=Back up this server with Kopia
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
Environment=KOPIA_CONFIG_PATH=/root/.config/kopia/repository.config KOPIA_CHECK_FOR_UPDATES=false
Nice=10
IOSchedulingClass=idle
ExecStart=/usr/bin/kopia snapshot create /etc /home /srv
KopiaUI and Kopia's server can also run snapshots on a schedule of their own, set in the policy. On a server, the timer is simpler to watch with systemctl --failed.
Licence and project health
We checked the projects' repositories on 14 October 2026.
- restic is under the BSD 2-Clause licence, and so is rest-server. It was started in 2014, has 36,500 stars on GitHub, and 46 people made changes in the last year, most of them by one main developer. The latest release is 0.19.1 from July 2026. It has no company behind it and no paid edition.
- Borg is under the BSD 3-Clause licence. It started in 2015 as a fork of Attic, has 13,800 stars, and 26 people made changes in the last year, most by its long-time lead developer, who is working on Borg 2. The latest stable release is 1.4.5 from July 2026; Debian 13 has 1.4.0. It has no paid edition.
- Kopia is under the Apache 2.0 licence. It started in 2015, has 14,300 stars, and 26 people made changes in the last year. The latest release is 0.23.1 from June 2026. Its version number is still below 1.0. It has no paid edition.
All three are free to use. What you pay for is the storage: a second server, or an S3 service.
Which one to pick
- Most servers: restic. Follow our restic guide. It was fast at backing up and restoring, used little memory, is in Debian, and its append-only REST server refused to delete anything when we tried. Its weaknesses: the backup server needs the repository's password to remove old backups, Debian's version lags behind the latest release, and a refused delete can still exit with status 0.
- Backups to an SSH server or storage box: Borg. It is mature, small, and stored the data as compactly as the others, and
borg compactruns without the key. On a small server it was the slowest by a factor of two, its append-only mode accepts a delete and leaves you to roll it back by hand, it uses the oldest key derivation of the three, and it has no S3 until Borg 2, whose new format will mean moving your backups. - A graphical interface, policies in one place, or object locks on S3: Kopia. One command backs up, applies retention and runs maintenance, and its repository server can refuse deletes per user. It used three times the memory, its cache can grow to 5 GB, it compresses nothing until you set a policy, and its restores took three to twelve times as long as restic's in our test. It is not in Debian, so updates come from Kopia's own repository.
Any of them runs on the server you already have: the backups need the space, not the speed. For the backup server, the Micro plan has 250 GB of storage, enough for many servers' worth of deduplicated backups. If you want S3 instead of a second server running SSH, Garage on a second server works with restic and Kopia.