Quick answer
How do I set up a Borg backup server on a VPS?
To set up a Borg backup server on a VPS, install Borg 1.x on both ends, create a borg user, and force borg serve --restrict-to-path --append-only on each client key. Initialise each repository with repokey; prune and compact from a separate admin key. A Coffervale 1 TB VPS costs $1.66 a month on 12 months (2 November 2026).
What are the steps, in order?
Install the same Borg 1.x on server and clients
apt install borgbackupon Debian or Ubuntu, then compareborg --versionon both ends.Create a borg user and a repository folder
One unprivileged account on the VPS owns every repository; clients never get a shell.
Force borg serve in authorized_keys
One line per client key, each limited to its own path with
--restrict-to-pathand--append-only.Initialise the repository with repokey
Run
borg init --encryption=repokeyfrom the client, then export the key and store it away from both machines.Schedule borg create on the client
Daily from cron or a systemd timer, with the passphrase read by
BORG_PASSCOMMAND.Prune and compact from an admin key
A second key without
--append-only, used from a trusted machine after checking the archive list.Check the repository and test a restore
borg checkweekly,--verify-datamonthly, and a realborg extractevery few months.
Which Borg version should the server run?
Run Borg 1.x on both ends: 1.4.5 was the latest stable release on 2 November 2026, and Borg 2 is still in beta. The Borg 2.0 page calls it a breaking release that is not directly compatible with Borg 1.x repositories, and renames borg init to borg repo-create. On Debian 13 the package to install is borgbackup (1.4.0 in trixie); the separate borgbackup2 package is a 2.0 beta. Install the same release on the server and on every client.
apt install borgbackup
borg --version
useradd --create-home --home-dir /srv/borg --shell /bin/sh borg
install -d -m 700 -o borg -g borg /srv/borg/.ssh /srv/borg/repos
install -d -m 700 -o borg -g borg /srv/borg/repos/laptop /srv/borg/repos/web1How do I lock each client to its own repository?
Put a forced borg serve command in front of every key in /srv/borg/.ssh/authorized_keys, so the key can run Borg and nothing else. The restrict keyword blocks port forwarding, agent forwarding and terminals, and Borg's documentation notes that it also covers SSH features added in future releases. The examples assume a POSIX shell as the account's login shell, which is why the user above gets /bin/sh.
--restrict-to-path PATHallows that path and every folder under it, so one client can hold several repositories.--restrict-to-repository PATHis stricter: exactly one repository, no sub-folders.--append-onlylets the key add archives but not remove data from the repository.--storage-quota 500Gcaps what one key can store, so a runaway client cannot fill the disk.
Each line stays on one line in the file; the admin key at the end has no --append-only and is used only for pruning.
command="borg serve --restrict-to-path /srv/borg/repos/laptop --append-only",restrict ssh-ed25519 AAAA...laptop-key... laptop
command="borg serve --restrict-to-path /srv/borg/repos/web1 --append-only --storage-quota 500G",restrict ssh-ed25519 AAAA...web1-key... web1
command="borg serve --restrict-to-path /srv/borg/repos",restrict ssh-ed25519 AAAA...admin-key... adminchown borg:borg /srv/borg/.ssh/authorized_keys
chmod 600 /srv/borg/.ssh/authorized_keysHow do I create the repository with repokey encryption?
Run borg init --encryption=repokey from the client, then export the key and keep it outside both the VPS and the machine you back up. Borg's documentation recommends repokey with a strong passphrase as the rule of thumb; repokey-blake2 is the same mode with a BLAKE2b hash, likely faster on processors without hardware-accelerated SHA-256. With repokey, the key sits in the repository's config file, sealed by your passphrase. Lose the passphrase and the backups are unreadable, by you and by everyone else. Borg also says you must keep an off-site copy of the key, for example on paper.
ssh-keygen -t ed25519 -N '' -C 'borg laptop' -f ~/.ssh/borg_ed25519
cat >> ~/.ssh/config <<'EOF'
Host coffer-borg
HostName 203.0.113.10
User borg
IdentityFile ~/.ssh/borg_ed25519
IdentitiesOnly yes
EOF
export BORG_REPO=ssh://coffer-borg/srv/borg/repos/laptop/main
borg init --encryption=repokey
borg key export --paper "$BORG_REPO" ~/borg-laptop-key.txt#!/bin/sh
export BORG_REPO=ssh://coffer-borg/srv/borg/repos/web1/main
# the passphrase file belongs to root, mode 600
export BORG_PASSCOMMAND='cat /root/.config/borg/passphrase'
borg create --stats --compression zstd,3 \
::'{hostname}-{now:%Y-%m-%dT%H:%M}' \
/etc /home /var/wwwHow do I prune and compact an append-only repository?
From a trusted admin machine, with the key that has no --append-only, after checking that no archive has gone missing. In append-only mode, Borg's notes explain, prune and delete still run but only tag data as deleted in a new transaction, and compaction never happens, with no warning and no error. Repository space is not freed until borg compact runs from a key allowed to rewrite.
The same notes carry the catch: the first write in normal mode makes every earlier deletion permanent, including one an attacker made through a client key. So list the archives first. If some are missing, stop and follow the recovery steps in Borg's append-only notes before you prune anything. A cron job that prunes automatically with an unrestricted key makes append-only pointless. Borg's documentation also recommends a --dry-run with --list before every real prune.
export BORG_REPO=ssh://coffer-admin/srv/borg/repos/web1/main
borg list
borg prune -v --list --dry-run --keep-daily=7 --keep-weekly=4 --keep-monthly=6
borg prune -v --list --keep-daily=7 --keep-weekly=4 --keep-monthly=6
borg compactHow do I check the repository and prove a restore works?
Run borg check weekly, borg check --verify-data monthly, and extract real files onto another machine every few months. A plain check verifies the repository and the archive metadata. --verify-data reads, decrypts and decompresses every chunk, which Borg calls very time consuming, and on hard disks it is. For a large repository, --repository-only --max-duration 3600 splits the repository check into one-hour slices that resume where they stopped. None of these replace an actual restore: a backup is only as good as the last time you got data out of it.
export BORG_REPO=ssh://coffer-borg/srv/borg/repos/web1/main
borg check -v
borg check -v --verify-data
borg check -v --repository-only --max-duration 3600
mkdir -p /tmp/restore-test && cd /tmp/restore-test
borg list
borg extract --list ::web1-2026-11-02T03:00 etc/nginxWhat does a Borg target cost compared with hosted Borg storage?
According to Coffervale's survey of 2 November 2026, hosted Borg storage cost $9.17 per TB a month at BorgBase (1 TB Medium plan, $110.00 a year) and $15.00 per TB at rsync.net, while storage VPS plans from hosts that take crypto without an ID document had a median of $4.00 per TB. Hosted services run the server for you; a storage VPS hands you root and the setup above, a choice weighed in Is a storage VPS a cheaper alternative to rsync.net or BorgBase?. We take no backup of your server and keep no copy of your data anywhere else, so what sits on a Coffervale storage VPS should be one of your copies, never the only one, so the Borg server is one copy among several, as How do I use a VPS for off-site backups? explains. The 1 TB plan is detailed in Where can I get a VPS with 1 TB of storage?, and if you prefer restic, read Restic: REST server or SFTP for backups to a VPS?. To encrypt the VPS disk as well, see How do I mount and format the storage disk on a Linux VPS?.
Borg targets per TB a month, 2 November 2026
| Borg target | Per TB a month | What you run yourself | Paid in crypto |
|---|---|---|---|
| BorgBase Medium, 1 TB | $9.17 ($110.00 a year) | Nothing: hosted Borg and restic repositories | Not stated |
| rsync.net, 0 to 9 TB tier | $15.00 | Nothing: ZFS storage reached over SSH | Not stated |
| Storage VPS, median of 99 plans | $4.00 | The Borg server set up on this page | Yes: hosts that take crypto without an ID document |
| Coffervale Clay, 1 TB | $1.66 on 12 months | The Borg server set up on this page | BTC, USDT, USDC, ETH, SOL, LTC |
Prices checked on
Prices as read on each service's own page on 2 November 2026. BorgBase bills the Medium plan yearly and states prices excluding VAT; the storage VPS median covers plans of 500 GB or more, in stock and billed monthly.
Questions about a Borg backup server
Do client and server need the same Borg version?
Keep both on Borg 1.x, ideally the same release. Borg 2 is still in beta, uses a new repository format and cannot open 1.x repositories directly. On Debian 13 install borgbackup, not borgbackup2.
Should I use --restrict-to-path or --restrict-to-repository?
--restrict-to-path allows a folder and everything under it, handy when one client keeps several repositories. --restrict-to-repository allows exactly one repository and no sub-folders, the tighter choice when each client has one.
Why does my repository not shrink after borg prune?
Prune only marks archives as deleted; borg compact frees the space. Through an append-only key, compaction never runs at all, so prune and compact from the admin key.
Can one storage VPS hold Borg repositories for several machines?
Yes. Give each machine its own key line in authorized_keys, its own path and, if the disk is shared, its own --storage-quota. One compromised client then reaches one repository only.
What happens if I lose the Borg passphrase?
The repository becomes unreadable for good. Borg cannot recover it and neither can the host. Keep the passphrase in a password manager and the exported key on paper, away from the VPS and the client.
Sources (13)
- Borg 1.4.5 documentation: Hosting repositories — BorgBackup project (read 2026-11-02)
- Borg 1.4.5 documentation: borg serve (restrict options, append-only, storage quota) — BorgBackup project (read 2026-11-02)
- Borg 1.4.5 documentation: borg init (encryption modes, key backup) — BorgBackup project (read 2026-11-02)
- Borg 1.4.5 documentation: borg prune — BorgBackup project (read 2026-11-02)
- Borg 1.4.5 documentation: borg compact — BorgBackup project (read 2026-11-02)
- Borg 1.4.5 documentation: borg check — BorgBackup project (read 2026-11-02)
- Borg 1.4.5 documentation: Additional notes, append-only mode — BorgBackup project (read 2026-11-02)
- Borg 1.4.5 documentation: Quick start (BORG_PASSCOMMAND) — BorgBackup project (read 2026-11-02)
- Borg 2.0 (preliminary information) — BorgBackup project (read 2026-11-02)
- BorgBackup releases (1.4.5 latest, 2.0.0b25 pre-release) — BorgBackup project on GitHub (read 2026-11-02)
- Debian trixie packages: borgbackup 1.4.0, borgbackup2 2.0.0b19 — Debian (read 2026-11-02)
- Plans and pricing borgbase.com — BorgBase (read 2026-11-02)
- Cloud storage pricing rsync.net/pricing.html — rsync.net (read 2026-11-02)