Proxmox Backup Server for VPS: How to Set Am Up
Use Proxmox Backup Server on VPS as offsite target. Learn datastore setup, namespaces, prune, garbage collection, encryption keys, and restore tests.
Wetin Proxmox Backup Server on VPS really dey give you
Proxmox Backup Server (PBS) for VPS na offsite target wey dey speak the same protocol wey your Proxmox VE (virtual environment) cluster already dey use. So, every backup after the first one na incremental, deduplicated across guests, encrypted before e comot your building, and you fit verify am afterwards. You go rent VPS with block volume, install PBS for Debian 13, create one datastore for that volume, then add am for Proxmox VE as storage of type pbs. The installation fit take ten minutes. Everything wey happen after that — namespaces, garbage collection, key custody, and restore wey you don actually run — na wetin go decide whether the backup still get value one year from now.
The reason to use PBS instead of copying vzdump files go rented disk na the chunk store. The client dey split each guest disk into chunks of about 4 MiB, hash dem, then upload only the chunks wey datastore never get before. For virtual machine wey dey run, QEMU dey track changed blocks with dirty bitmap after the first backup. So, the next run go read only those blocks from local disk. If guest get 200 GB and e dey change 3 GB every day, e go send about 3 GB every day. Na this make home uplink and rented volume fit work together. Na also why VPS as offsite backup target better pass spare drive for friend house. If you still dey decide where the hypervisor itself suppose dey, Proxmox for house versus rented VPS explain that question separately.
Size volume before you rent am
Sizing na arithmetic wey you go do with your own numbers. Take the space wey each guest dey actually use, no be the size of the virtual disk, then add wetin e dey change every day multiplied by the number of days wey you dey keep am. Compression and deduplication both fit reduce this figure, so treat the result as ceiling, no be target.
The data behind this chart
[
{
"label": "web VM",
"used_gb": 40,
"daily_change_gb": 0.8,
"store_gb": 64
},
{
"label": "mail VM",
"used_gb": 120,
"daily_change_gb": 3.0,
"store_gb": 210
},
{
"label": "file server container",
"used_gb": 300,
"daily_change_gb": 1.5,
"store_gb": 345
}
]Those rows na worked example, no be measurement. Read the used space from df -h inside each guest, and read the daily change from the size of the second and third backups for the PBS task log after dem don exist.
The mail guest for the example dey use 120 GB and e dey change about 3.0 GB every day, so thirty daily snapshots need roughly 210 GB: one full copy plus thirty days of changes. Add the last column across all 3 guests and the total go be about 619 GB. Add one-fifth on top for indexes, metadata, and the space wey garbage collection need to work, and that point to 1 TB volume.
The rest of the plan small. PBS dey okay with 2 GB of RAM and e go comfortable with 4 GB, because the expensive work dey happen for cluster side: the Proxmox VE node dey read the guest disks and do the chunking and hashing. Wetin the VPS dey do na write chunks and run the two heavy jobs, garbage collection and verification. Rent the datastore as separate block volume instead of one large root disk, because you fit grow volume later without rebuilding the server.
Install Proxmox Backup Server for Debian 13
For August 2026, the current pairing na Proxmox Backup Server 4 for Debian 13, codename trixie. Older guides dey pair PBS 2 with Debian 11, and codename dey inside repository definition. So, if you copy old suite name, apt go show error say release file dey miss. Start with plain Debian 13 image. Run everything below as root, or use sudo as e dey written.
sudo apt update && sudo apt install -y wget
sudo wget https://enterprise.proxmox.com/debian/proxmox-archive-keyring-trixie.gpg -O /usr/share/keyrings/proxmox-archive-keyring.gpg
sha256sum /usr/share/keyrings/proxmox-archive-keyring.gpgThe sum suppose read 136673be77aba35dcce385b28737689ad64fd785a797e57897589aed08db6e45. If e no be so, stop. Wrong keyring mean say you wan install packages wey something you never verify sign.
Write /etc/apt/sources.list.d/pbs.sources with no-subscription repository. Na the correct one for server wey no get support contract:
Types: deb
URIs: http://download.proxmox.com/debian/pbs
Suites: trixie
Components: pbs-no-subscription
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpgsudo apt update
sudo apt install -y proxmox-backup-serverWeb interface dey answer for HTTPS port 8007. Log in as root@pam with system root password, because PBS dey authenticate that user through PAM (pluggable authentication modules). Na the same accounts operating system dey use. Certificate na self-signed, and your browser go tell you so. Proxmox VE pin that certificate fingerprint later, so the warning dey expected; e no be problem wey you need fix.
Port 8007 na login form for public internet, so no leave am open to everybody. One nftables file cover am. Writing /etc/nftables.conf flushes current ruleset, so skip this if another thing already dey manage firewall for this server.
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif lo accept
tcp dport 22 accept
ip saddr 203.0.113.7 tcp dport 8007 accept
}
}Apply am with sudo systemctl enable --now nftables, and leave second SSH session open while you dey do am: policy drop plus one typo for SSH rule fit lock you out of your own server. Replace 203.0.113.7 with the address wey your cluster dey connect from. If that address dey change, either widen the rule to your provider's range or end the connection inside tunnel. Also remember say most VPS panels get separate network firewall in front of the machine, and that firewall must allow the same port.
Put datastore for im own volume
Datastore no suppose dey for root filesystem. When datastore fill shared root filesystem, backup go fail, and everything else for the server go fail too, including the logging wey you need to find out why. Attach block volume, format am, mount am, and na after that you go create datastore inside the mount point.
lsblk
sudo mkfs.ext4 -L pbsstore /dev/vdb
sudo mkdir -p /mnt/datastore/store1Take device name from lsblk. E dey be /dev/vdb for most KVM images and /dev/sdb for some others, and e no safe ever to assume. Add the mount to /etc/fstab by label, so if device name change after reboot, e no go point datastore to wrong disk:
LABEL=pbsstore /mnt/datastore/store1 ext4 defaults,relatime 0 2sudo systemctl daemon-reload
sudo mount -a
findmnt -no SOURCE,TARGET,OPTIONS /mnt/datastore/store1findmnt suppose print device, path, and options wey include rw,relatime. Two failures dey hide for that one line. If mount no dey there and you create datastore anyway, PBS go write inside root filesystem underneath the mount point. The next successful mount go hide that data without deleting am. Datastore go then look empty, while root filesystem still full. If options talk say noatime, PBS no go work, because e dey run access time safety check when dem create datastore and again for every garbage collection.
sudo proxmox-backup-manager datastore create store1 /mnt/datastore/store1
sudo proxmox-backup-manager datastore listThat one go create .chunks directory wey get 65536 subdirectories, named 0000 through ffff. Datastore na hundreds of thousands of small files, no be just few big ones. Two things follow from this. Copying datastore with ordinary file-level tool slow reach the point of uselessness. Also, provider volume snapshot wey dem take while backups dey run no be consistent copy of am. Na the same reason snapshots no replace backups anywhere else.
Namespaces dey stop two hosts from colliding
Datastore dey flat by default. Backups get names like vm/100, ct/101 and host/<name>. Two clusters wey each get guest with ID 100 go write inside the same group. Their snapshots go mix together, and retention rule wey you write for one fit count the other one's snapshots. Namespaces give every source its own tree inside one datastore.
Create dem for the PBS host. The --repository argument get form [[auth-id@]server[:port]:]datastore, so local one go be root@pam@localhost:store1, and the command go ask for root password.
sudo proxmox-backup-client namespace create --repository 'root@pam@localhost:store1' pve-home
sudo proxmox-backup-client namespace create --repository 'root@pam@localhost:store1' pve-office
sudo proxmox-backup-client namespace list --repository 'root@pam@localhost:store1'Deduplication no change because of this split. Chunks dey shared across the whole datastore, so ten Debian guests wey spread across three namespaces still go store only one copy of the base system. Na this make one datastore with namespaces better than one datastore per host: separate datastores mean separate chunk pools, and separate chunk pools mean you go pay for the same Debian install several times.
Give every source its own account, and limit am to its own namespace. An API (application programming interface) token na credential wey belong to a user and get its own permissions. Na this you want for machine wey fit get stolen.
sudo proxmox-backup-manager user create backup@pbs --email you@example.com
sudo proxmox-backup-manager user generate-token backup@pbs pve-home
sudo proxmox-backup-manager acl update /datastore/store1/pve-home DatastoreBackup --auth-id 'backup@pbs!pve-home'The token command go print the secret only once:
Result: {
"tokenid": "backup@pbs!pve-home",
"value": "d63e505a-e3ec-449a-9bc7-1da610d4ccde"
}Copy am now, because PBS no keep any version wey e fit show you again. Check the access control command carefully. E name the token, backup@pbs!pve-home, not the user, because PBS dey calculate token permissions only from entries wey name the token itself. Entry for backup@pbs alone go leave the token without any access, and the first backup go fail because of permissions, not because of anything visible for the network. The path matter too: token wey scope to /datastore/store1/pve-home no fit read or delete anything for the office namespace, so one breached cluster no fit destroy another site's history.
Add VPS as backup storage for Proxmox VE
First read the certificate fingerprint for the PBS host.
sudo proxmox-backup-manager cert info | grep FingerprintThen, for any node inside the cluster:
sudo pvesm add pbs pbs-offsite --server pbs.example.com --datastore store1
sudo pvesm set pbs-offsite --username 'backup@pbs!pve-home' --password
sudo pvesm set pbs-offsite --fingerprint 'FINGERPRINT_FROM_CERT_INFO'
sudo pvesm set pbs-offsite --namespace pve-home
sudo pvesm set pbs-offsite --prune-backups keep-all=1Paste the value wey cert info print for the placeholder on the third line. If you pass --password without value, pvesm go ask you for am, so the token secret no go enter your shell history. E store am for /etc/pve/priv/storage/pbs-offsite.pw, while the storage definition itself go enter /etc/pve/storage.cfg. Proxmox VE go replicate am to every node for the cluster, so you configure this once for the whole cluster.
--prune-backups keep-all=1 tell Proxmox VE make e delete nothing. Retention dey happen for the PBS side, and we go cover am later. The reason clear: the token no need permission to delete. So if ransomware encrypt the cluster, the cluster no fit reach the offsite history and prune the backups wey suppose save am.
sudo pvesm status --storage pbs-offsite
sudo vzdump 100 --storage pbs-offsite --mode snapshotpvesm status print active for the status column, together with the datastore total space and used space. inactive mean say the node no fit complete TLS (transport layer security) session to port 8007. That one na firewall or fingerprint problem, no be credential problem.
The first backup go upload everything, so calculate the time before you start am. 200 GB na 1600 gigabits, and 100 Mbit uplink dey move 0.1 gigabit every second. So the minimum time na about four and a half hours, and real time fit longer. Start am when you no need the bandwidth. Every run after that go send only new chunks.
Client-side encryption, and where the key dey
The VPS na computer wey you no own. Encrypt for client side, and the datastore go hold chunks wey provider no fit read.
sudo pvesm set pbs-offsite --encryption-key autogenThat one go write new key to /etc/pve/priv/storage/pbs-offsite.enc. Na root fit read am. E dey replicated with the rest of /etc/pve. From the next backup, client go encrypt each chunk before e comot. Server still fit list your snapshots and their sizes, but e no fit read their contents.
Now na this part dey make am backup instead of liability. Generated key no get passphrase, and e dey only for the cluster wey e dey protect. If person steal that cluster or encrypt am, VPS go hold data wey nobody fit open. Copy the key comot from the cluster on the day wey you create am.
sudo cp /etc/pve/priv/storage/pbs-offsite.enc /root/pbs-offsite.enc
sudo proxmox-backup-client key paperkey /root/pbs-offsite.enckey paperkey go print the key as document wey you fit print on paper and keep for another place. Treat the file itself as secret, because anybody wey hold am fit decrypt every backup wey use am. For bigger setup, PBS still support master key: na RSA (Rivest Shamir Adleman) key pair wey you create with proxmox-backup-client key create-master-key. Each backup go store its own encryption key encrypted with the public half, while the private half stay offline for recovery.
You need know one consequence of this design before you start, not after. For encrypted backups, system calculate chunk digest from the plain text content joined with the encryption key. So two identical chunks wey different keys encrypt go produce different digests, and dem no go deduplicate against each other. If you change the key, next backup go upload everything again. The old chunks go remain there until their snapshots get pruned and collected. Decide about encryption before the first upload.
Prune mark, garbage collection dey reclaim space
Na this section people dey skip, and na im dey fill the volume. When you prune snapshot, e remove the snapshot metadata: the manifest, the indexes, the log, and the notes. E no delete any chunk. Snapshots dey share chunks, so nobody fit know say chunk no dey use until e read every remaining index, and garbage collection na the job wey dey read dem. Datastore wey get prune schedule but no garbage collection schedule go only dey grow.
Set both. Do retention first, with one job for each namespace:
sudo proxmox-backup-manager prune-job create home-daily --store store1 --ns pve-home --schedule '02:30' --keep-daily 14 --keep-weekly 8 --keep-monthly 6
sudo proxmox-backup-manager prune-job listThen set the collection schedule for the datastore. Make e run some hours after the prune job and outside the backup window:
sudo proxmox-backup-manager datastore update store1 --gc-schedule 'Sun 04:27'
sudo proxmox-backup-manager datastore show store1Prove the difference to yourself once, for the PBS host:
df -h /mnt/datastore/store1
sudo proxmox-backup-manager garbage-collection start store1
df -h /mnt/datastore/store1Run the prune job, then df, and the used figure no go change. Run garbage collection, then df again, and e go change.
Garbage collection dey run for two phases. Phase one dey go through every index for the datastore and update the access time of every chunk wey those indexes reference. Phase two dey delete chunks wey their access time older than the cutoff. The cutoff na 24 hours and 5 minutes before the run start, or the start time of the oldest backup wey still dey write, whichever one come earlier. This margin dey exist because Linux mounts filesystems with relatime by default. This setting dey update access time roughly once every day instead of after every read. So, chunk wey dem write one hour ago no go ever delete, even if nothing dey reference am yet. Space wey prune free go show for the first collection wey run more than one day after the chunk dem last touch. If datastore look like e reclaim nothing, e often mean say e still dey inside this waiting window.
For small VPS, na the heaviest job wey the box dey run, because e dey stat every chunk file for the volume. The task log dey end with summary of wetin dem remove and wetin still dey pending because of the grace period. If plenty dey pending, run am again the next day. PBS exposes gc-atime-safety-check and gc-atime-cutoff as datastore tuning options, and make you leave both as dem be. Dem dey exist for storage wey no fit record access times. If you turn off the safety check for filesystem wey dem mount with noatime, na so you fit lose chunks wey live snapshots still dey reference.
Verification show say the chunks still dey readable
Backup wey upload cleanly fit still become unreadable after one year. Verification dey read the chunks again and compare dem with the checksums wey dey stored for the index. This one make system find damage according to schedule instead of during restore.
sudo proxmox-backup-manager verify store1 --read-threads 1 --verify-threads 4Keep the thread counts low for small VPS. Disk and CPU dey limit verification, and e fit compete with other work wey the server dey do. For schedule, use the datastore's Verify Jobs tab for the web interface. Weekly job wey skip snapshots wey verification don already cover, then verify anything wey older than 30 days again, go cover the whole store over time without repeating work.
Snapshot wey verification fail go dey marked as failed for the datastore view. No ignore am. Chunks dey shared, so one damaged chunk from base image fit make every snapshot wey reference am fail. To repair am, forget the failed snapshots and run fresh backup. This one go upload the missing chunks again. If failures continue to show, suspect the storage under the datastore. Set up disk health monitoring for the VPS so the drive fit alert you before the verify job does.
Test restore first, then test am without the cluster
You no go know whether backup dey work until you restore one. These two tests dey check different things.
Whole guest, for the cluster:
sudo pvesm list pbs-offsite
sudo qmrestore 'pbs-offsite:backup/vm/100/2026-08-14T22:00:00Z' 999 --storage local-lvmThe first column for pvesm list na the volume ID, and timestamp dey inside am, so copy your own instead of typing the example. Restore am into an unused guest ID and use different storage, then start am with the network interface disconnected. No ever restore over a guest wey dey run just to check whether backup dey work, because if restore fail halfway, you go lose the working copy too.
The second test na the one wey almost nobody dey run. Assume say the building wey hold the cluster don disappear, then restore from a machine wey never belong to the cluster. For any Debian 13 box, add the client-only repository as /etc/apt/sources.list.d/pbs-client.sources:
Types: deb
URIs: http://download.proxmox.com/debian/pbs-client
Suites: trixie
Components: main
Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpgsudo apt update && sudo apt install -y proxmox-backup-client
export PBS_REPOSITORY='backup@pbs!pve-home@pbs.example.com:store1'
export PBS_PASSWORD='<the token secret>'
export PBS_FINGERPRINT='<the value cert info printed>'
proxmox-backup-client snapshot list --ns pve-home
proxmox-backup-client snapshot files vm/100/2026-08-14T22:00:00Z --ns pve-home
proxmox-backup-client restore vm/100/2026-08-14T22:00:00Z 'ARCHIVE_NAME_FROM_THAT_LIST' ./restore-test --keyfile ./pbs-offsite.enc --ns pve-homePut the three quoted placeholders with your own values, and take the archive name for the last line from wetin snapshot files print. This one prove wetin the first test no fit prove: say your copy of the key file fit decrypt real data, and say you fit run the client from a machine wey never hold your cluster configuration before. Write down the four values wey e need, the repository string, the token secret, the fingerprint, and the key file. Keep dem together for the place wey your disaster plan point to.
Wetin deduplication dey do and e no dey do to your disk bill
Deduplication na real thing, and e dey work across the whole datastore. Ten Debian guests dey share one copy of the base system among dem, so the second identical guest almost no cost anything to store. E save upload bandwidth too, because the client dey send checksum instead of data for any chunk wey the server don already hold.
Wetin e no dey do, make we talk am plainly.
- E no dey reduce data wey dey change. Database wey dey rewrite big parts of its files every night dey produce new chunks every night, and retention dey multiply dem.
- E no dey cross encryption key boundary, as we don explain above.
- E no dey cross datastore boundary, and na the main reason for namespaces.
- E no dey stop volume from fulling up. When datastore full, backups fail, and the only answers na bigger volume or shorter retention.
No put another deduplication layer underneath am. Client don already deduplicate and compress the chunks before dem arrive, so ZFS deduplication under a datastore dey use RAM to find matches wey client don remove before writing. Plain ext4 or xfs for the volume na the correct choice here.
Web interface dey report deduplication factor for the datastore. That number describe your guests, and na the only one wey make sense to plan with, because published ratios dey describe another person data. If you also need file-level backups for machines wey no be Proxmox guests, run dem alongside for the same VPS: PBS na hypervisor-aware target for whole guests, while restic and BorgBackup dey point to directories, and restic backups to a VPS fit cover laptops and standalone servers wey PBS never intend to cover.
Failure modes and wetin you go see
Storage dey show inactive. pvesm status --storage pbs-offsite dey print inactive when node no fit complete TLS session to port 8007. Check firewall for VPS, then provider separate network firewall, then fingerprint. Fingerprint wey no longer match certificate go fail for the same way wey blocked port dey show, and e dey change anytime dem replace that certificate.
The first backup fail because of permissions. Access control entry gatz name token instead of user, and e gatz cover namespace wey storage dey point to. Confirm both for datastore permissions tab inside web interface before you check anywhere else.
Garbage collection no gree start. Access time safety check fail. This almost always mean say datastore filesystem mount as noatime. Run findmnt -no OPTIONS /mnt/datastore/store1 to confirm, fix the option for /etc/fstab, then remount. No disable the check just to pass am.
Datastore dey only grow. Prune jobs dey run but nothing dey reclaimed. Either garbage collection schedule no dey, or every collection dey enter the 24 hour grace window because e dey run immediately after backups. Check schedule with proxmox-backup-manager datastore show store1.
Backup wey dey quick before now dey take hours. Guest wey dem stop, migrate, or restore go lose dirty bitmap. So the next run go read the whole disk for cluster side, even though e upload very small amount. Task log go show long duration with small upload figure, and the next run go quick again. If every job for VPS slow instead, the cause usually dey outside datastore, and CPU steal time from noisy neighbour na the first thing to measure.
FAQ
Why my Proxmox Backup Server datastore dey continue grow when prune job run?
Pruning only dey remove snapshot metadata: the manifest, the indexes, the log and the notes. The chunks go remain for disk until garbage collection delete the ones wey no index dey reference again. Give the datastore schedule with proxmox-backup-manager datastore update store1 --gc-schedule 'Sun 04:27', then prove am by running df -h for datastore path before and after proxmox-backup-manager garbage-collection start store1. Expect say e fit take at least one day, because phase two only dey remove chunks wey their access time old pass 24 hours and 5 minutes.
How much disk Proxmox Backup Server VPS need?
Add the space wey each guest dey really use, then add each guest daily change multiplied by the number of days wey you dey keep. That total na ceiling, because compression and deduplication both dey help you. Add about one-fifth for indexes and working room, then round am up to volume size wey you fit buy. Check am again after two weeks against the real usage for datastore view, because guess wey you make before first backup always dey wrong for one direction or the other.
Where I suppose store the backup encryption key?
Store am anywhere, except only for the cluster wey e dey protect. Proxmox VE dey keep am for /etc/pve/priv/storage/<storage>.enc, and e dey replicate am to every node, so the cluster fit lose am completely. Copy am out on day one, print am with proxmox-backup-client key paperkey, and keep that copy for another building. Also note say the key dey take part for chunk digest, so if you replace am later, the next backup go upload everything again.
I need one datastore for each Proxmox host, or namespaces?
Use one datastore, with one namespace for each source host or cluster. Deduplication dey work across one datastore, but e no dey work between datastores, so splitting by host go store the same base images several times. Namespaces dey keep backup groups separate, so two hosts wey both get guest with ID 100 no go collide. Access control path wey follow the form /datastore/store1/pve-home go limit each host API token to only its own namespace.
Small VPS go fit keep up as Proxmox backup server?
Usually yes, for homelab, because chunking and hashing dey happen for Proxmox VE node, not for backup server. The VPS dey write chunks and run the two heavy jobs: garbage collection and verification. Give am 4 GB of RAM and keep verification thread counts low. Schedule both jobs outside backup window. If dem still dey take much longer than the disk suppose need, measure steal time before you buy bigger plan.