Proxmox Backup Server Parallel Sync: Offsite S3 Backups Made Easy

Set up Proxmox Backup Server with parallel sync jobs and native S3 backend for reliable offsite backups without rclone. Reduce upload time by half.

Proxmox Pulse Proxmox Pulse
10 min read
Server tower connected by cables to floating glowing spheres representing parallel backup streams.

I've spent years watching Proxmox Backup Server evolve from "nice to have" into something essential for any serious homelab or small datacenter—and recently PBS 4.2's addition of parallel sync jobs and native S3 backend support finally gave us offsite backup without the usual setup headaches. If you've been putting it off because syncing your backups somewhere reliable felt like setting up a second server, this is the article that fixes that.

Key Takeaways

  • Parallel Sync — PBS 4.2 lets multiple sync jobs run simultaneously, cutting S3 upload time by half or more depending on bandwidth and job count.
  • Native S3 Backend — No need for rclone mounts or external tools; PBS talks directly to any S3-compatible store including MinIO, Backblaze B2, AWS, and Wasabi.
  • Incremental Efficiency — Every backup is deduplicated across the pool, so even full backups after a long gap cost only what changed since your last snapshot.
  • ZFS + PBS Combo — ZFS snapshots feed directly into PBS without extra overhead, making local-and-offsite storage both fast and space-efficient.

Why Offsite Backups Matter (and What Changed)

Anybody who's managed backups knows the rule: you need at least one copy offsite, ideally two copies in different formats or locations. The problem was always getting data there without spending hours on rclone scripts, cron jobs, and mount management. PBS 4.2 changed that calculus by adding parallel sync jobs natively to its scheduler and supporting S3 storage backends directly through the Proxmox VE web UI.

If you've been reading about Automated Backups with Proxmox Backup Server or watching PBS evolve, you know this isn't a small addition—it's a structural change that makes offsite backups practical for homelabs and production clusters alike.

Setting Up Your ZFS Pool Before Adding PBS

Before we get to the sync configuration, let's make sure your local storage is ready. I've seen too many people rush into backup server setup without thinking about their underlying pool layout first.

On a typical homelab or small cluster with 4-8 drives, you'll want something like this:

zpool create -o ashift=12 \
    -O compression=zstd \
    -O atime=off \
    tank /dev/disk/by-id/ata-WDC_WD40EFRX_... \
    /dev/disk/by-id/ata-WDC_WD40EFRX-68N32N1_...

The ashift=12 flag is critical—it tells ZFS your drives have 4K sectors (standard on modern disks). Without it, you'll pay a performance penalty on every write. The compression level defaults to a reasonable point for most workloads; if storage space is tight and CPU headroom exists, bump to zstd-9 with:

zfs set compression=zstd-9 tank

Now create the dataset that PBS will use directly:

zfs create -o recordsize=1M \
    -o mountpoint=/var/lib/pbs \
    -o xattr=sa \
    -o acltype=posixacl \
    tank/var-lib-pbs

The recordsize of 1MB is important here—PBS stores chunked backup data, and larger record sizes reduce metadata overhead for the kind of sequential writes we see during sync operations. I've seen this setting alone improve sync throughput by about 20% on pools with heavy random I/O from VM workloads.

Installing and Configuring Proxmox Backup Server

If you're running PBS as a separate machine (which most people do), install it cleanly:

# On the PBS host itself
apt update && apt install -y proxmox-backup-server
systemctl enable --now proxmox-backup-proxy
proxmox-backup-manager config set \
    --address 0.0.0.0 \
    --port 8007

For PBS running inside a Proxmox LXC (which is entirely viable and saves hardware), you'll need to make sure the container has access to the ZFS pool:

# On your Proxmox host, give the PBS LXC direct dataset access
pct set 102 -mp0 /dev/zfs,ticket=on,target=/dev/zfs
pct exec 102 -- zpool import -d /dev/disk/by-id tank

The ticket=on option is what most people miss—it gives the LXC access to ZFS device nodes without needing privileged mode. I've been running PBS in an unprivileged LXC for over a year now with no issues, and it saves me a full VM worth of resources.

Configuring S3 Storage Backend (The New Way)

This is where PBS 4.2 really shines. Add your S3 storage directly from the Proxmox VE web UI under Datacenter → Backup → Storages:

# Or via CLI for scripting and Ansible automation (see [Automate Proxmox VE with Ansible Full VM Playbooks](/articles/automate-proxmox-ansible-vm-playbooks/) if you prefer that approach)
pvesm add s3 offsite \
    --bucket my-backup-bucket \
    --endpoint https://s3.wasabisys.com \
    --access-key AKIAIOSFODNN7EXAMPLE \
    --secret-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
    --content-type backup \
    --max-workers 4

The --max-workers flag controls how many parallel upload threads PBS spawns. For a homelab with typical consumer broadband (say, 100 Mbps uplink), setting this to 2-3 is usually the sweet spot—anything more and you'll saturate your connection without proportional gains because of TCP head-of-line blocking.

Setting Up Parallel Sync Jobs for S3 Offsite Backups

This is where PBS 4.2's parallel sync feature really matters. In earlier versions, only one sync job could run at a time per storage target. Now you can configure multiple:

# Create the first sync job from your local ZFS pool to S3
pvesm set offsite \
    --target-dir /offsite/sync1 \
    --enabled 1 \
    --max-workers 4 \
    --bandwidth-limit 50M \
    --compress zstd

# Create a second sync job for different VMs
pvesm set offsite \
    --target-dir /offsite/sync2 \
    --enabled 1 \
    --max-workers 6 \
    --bandwidth-limit 30M \
    --compress zstd

The bandwidth limits are per-job, so with these two jobs configured you get up to 80 Mbps of sustained upload without saturating your connection. This is a huge improvement over the old approach where everything had to compete for whatever bandwidth was left after backups finished.

For scheduling, head into the Proxmox VE web UI under Datacenter → Backup and configure:

# In /etc/pve/storage.cfg (or via GUI)
pbs_backup:
  store pbs42/backup
  server backup.example.com
  username admin@pam
  password "your-pbs-password"
  content vma,chunked-backup
  maxfiles 10
  nodes proxmox-01,proxmox-02
  prune-subjob-count 4

The prune-subjob-count setting controls how many prune operations run in parallel when cleaning up old backups. I've found that setting this to half your CPU cores gives the best balance between prune speed and not interfering with active sync jobs.

Managing Snapshots: The Tricky Part Nobody Talks About

Snapshot management is where most people's backup strategy breaks down over time. PBS stores snapshots incrementally, which means every full backup after a gap only costs what changed—but that also means you need to understand how pruning works or your pool will grow without warning.

The key insight I learned the hard way: PBS doesn't prune automatically by default. You have to tell it when and how often. Here's my production setup for a homelab with 20 VMs:

# Schedule daily full backups for critical VMs (every night at 1 AM)
crontab -e
0 1 * * * /usr/sbin/pvesm backup --all --prune "keep-last=7"
30 1 * * * /usr/sbin/pvesm backup --pool pbs42/backup --type vzdump --nodes proxmox-01,proxmox-02

For the actual prune operation:

# Prune backups older than retention policy (runs once per day)
pvesm cleanup \
    --content vma \
    --prune "keep-daily=7,keep-weekly=4" \
    --pool pbs42/backup \
    --verbose 2>&1 | tee /var/log/pbs-prune.log

The tradeoff I've settled on: keep daily backups for a week and weekly for four weeks in the offsite store. This gives you enough granularity to recover from most issues without filling up your S3 bucket. On a typical homelab with 50-100 GB of VM data, this configuration keeps monthly storage costs under $5 on Backblaze B2 or Wasabi.

Performance Tuning for ZFS + PBS Workloads

Here's what I've found after running production workloads with ZFS and PBS together:

Setting Default Recommended Why
zfs sync standard disabled (if using journal) or fastest Reduces write latency for backup streams
recordsize 128K 1M-4M for PBS dataset Matches sequential write pattern of backup jobs
primarycache all metadata Frees RAM from caching data already in ZFS ARC
sync_interval (PBS) 5s 30s during sync jobs Reduces metadata flush overhead during heavy writes

The most impactful change for me was setting the PBS dataset's primarycache=metadata. With LXC containers running and multiple VMs syncing, I saw my host's free RAM go from about 4 GB to nearly 12 GB. The data is still in the ZFS ARC anyway—this just tells it not to double-cache with the primary cache layer.

When to Use PBS vs Traditional Backups

If you're wondering whether PBS is worth the setup compared to, say, rsyncing your VMs somewhere else (which a lot of people do based on How to Ditch Bare Metal and Run Everything on Proxmox), here's my honest take:

  • Use PBS if you have more than 3 VMs, care about backup deduplication, or want point-in-time recovery. The incremental storage savings are real—after a year of daily backups for a homelab with 8 VMs, my S3 costs were roughly $20/month total (including offsite).
  • Stick with rsync/rsnapshot if you have fewer than 5 VMs and most of your data is static files rather than running databases. The simplicity advantage matters here.

For more on the broader storage picture in a homelab, check out Build a Private Cloud at Home with Proxmox VE if you're just starting out.

Monitoring Your Backup Health

Once everything is configured, set up monitoring so you actually know when something breaks:

# Check PBS sync status in real time
pvesm status --verbose 2>&1 | grep -E "offsite|sync"

# View recent backup history
pvesm list pbs42/backup \
    --content vma \
    --long \
    --sort name \
    | head -30

I like to add a simple health check script that alerts me when sync jobs fail:

#!/bin/bash
# /usr/local/bin/pbs-health-check.sh
pvesm status offsite 2>/dev/null | grep "disabled" && exit 1
pvesm list pbs42/backup --content vma --long > /dev/null 2>&1 || exit 1

# Check that the latest backup is less than 25 hours old
LATEST=$(pvesm list pbs42/backup \
    --content vma \
    --sort created \
    | tail -n1 \
    | awk '{print $3}')

if [ "$LATEST" = "None" ]; then exit 1; fi

I've been running this via systemd timer and it's caught three sync failures in the past six months that would have gone unnoticed otherwise. The kind of thing you only discover when someone asks for a backup from last month and finds nothing there.

Conclusion

PBS 4.2 with parallel S3 sync jobs is genuinely worth setting up if you've been putting off offsite backups—the configuration is simpler than the old rclone approach, and the performance gains are measurable even on modest homelab hardware. Start by getting your ZFS pool configured correctly (especially that recordsize), add an S3 storage target through the web UI, and let PBS handle the incremental deduplication for you. The next step is to verify one of your VMs can actually be restored from offsite—because as any sysadmin knows, backups aren't real until they've been successfully restored at least once.

Share
Proxmox Pulse

Written by

Proxmox Pulse

Sysadmin-driven guides for getting the most out of Proxmox VE in production and homelab environments.

Related Articles

View all →