Proxmox VEXIV · Disaster RecoveryMulti-site architecture
Choosing a replication strategy: ZFS send, Ceph RBD mirror, PBS sync
What you'll learn
- Place ZFS replication, RBD mirroring and PBS sync on the same RPO/RTO/cost axes
- Explain why a replicated copy is not a backup and what each mechanism does with a deletion
- State honestly what Proxmox supports for Ceph cross-site replication and what it does not
- Combine mechanisms so that every named failure has exactly one recovery path
Prerequisites
Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-12
“We replicate to the DR site” is a sentence that can mean three completely different things, with RPOs ranging from seconds to a day and recovery behaviours that differ in kind, not just in degree.
This lesson puts all three on the same axes so the sentence has to become specific.
The three mechanisms
ZFS replication (pvesr) | Ceph RBD mirroring | PBS sync | |
|---|---|---|---|
| What moves | ZFS snapshot deltas | RBD journal or snapshot deltas | Deduplicated chunks |
| Typical RPO | 1 - 60 min (scheduled) | Seconds to minutes | 1 - 24 h (scheduled) |
| RTO at the far end | Minutes - start the guest | Minutes - promote and start | Hours - restore the guest |
| Point-in-time history | Only retained snapshots | Effectively none | Full retention policy |
| Deduplication | None across guests | None | Global across the datastore |
| Survives a deletion? | Only within snapshot retention | No | Yes |
| In Proxmox’s UI | Yes, fully | No | Yes, fully |
| Storage cost at far end | Full copy | Full copy | Deduplicated, compressed |
| Guest downtime to recover | Start on the far node | Promote, then start | Full restore transfer |
Read down the “survives a deletion” row. It is the row that decides whether a mechanism is a backup, and two of the three answer no.
ZFS replication with pvesr
The mechanism Proxmox integrates for local-storage clusters. A scheduled
incremental zfs send of the guest’s dataset to another node.
set -euo pipefail
VMID=100
TARGET=pve-02
pvesr create-local-job "$VMID-0" "$TARGET" --schedule '*/15'
pvesr list
pvesr status# pvesr statusJobID Enabled Target LastSync NextSync Duration FailCount State
100-0 Yes local/pve-02 2026-08-12_09:15:02 2026-08-12_09:30:00 12.44 0 OK
101-0 Yes local/pve-02 2026-08-12_09:15:04 2026-08-12_09:30:00 31.09 0 OK
104-0 Yes local/pve-03 2026-08-11_22:45:11 2026-08-12_09:30:00 0.00 7 command 'zfs send' failedIllustrative output
Job 104-0 is the one to notice. FailCount 7 and a LastSync eleven hours
old means that guest’s DR copy is eleven hours behind while every dashboard
still shows a replication job configured for it.
Strengths. No shared storage required, so it works on the cheapest possible cluster. Fully integrated - the HA stack knows about it and can recover a guest onto a replication target. The transfer is a block-level delta, so a guest that changed little sends little.
Limits worth stating plainly.
- Pairwise and directional. A guest replicated to
pve-02cannot be recovered onpve-03. Your HA target set for that guest is one node. - Recovery is a rollback. The guest resumes at the last replicated snapshot; everything after it is gone and the application does not know.
- The schedule is the RPO. A 15-minute schedule is a 15-minute RPO, and that number belongs in whatever document promises one.
- Failures are quiet. A failing job increments a counter. Nothing pages.
set -euo pipefail
MAX_AGE_MIN=45
BAD=0
# Columns: JobID Enabled Target LastSync NextSync Duration FailCount State
# Process substitution, not a pipe: a pipe would run the loop in a subshell
# and BAD would never survive back to the exit.
while read -r JOB _EN TARGET LAST _NEXT _DUR FAILS REST; do
# LastSync is YYYY-MM-DD_HH:MM:SS; convert for date(1).
WHEN=${LAST//_/ }
AGE=$(( ( $(date +%s) - $(date -d "$WHEN" +%s) ) / 60 ))
if [ "$FAILS" -gt 0 ] || [ "$AGE" -gt "$MAX_AGE_MIN" ]; then
printf 'STALE %-8s target=%-16s age=%dmin fails=%s state=%s\n' \
"$JOB" "$TARGET" "$AGE" "$FAILS" "$REST"
BAD=1
fi
done < <(pvesr status | tail -n +2)
exit "$BAD"Ceph RBD mirroring
The honest position first, because it is the reason this section is short.
Two modes exist, and the choice between them is the usual latency-versus-cost trade:
| Mode | Mechanism | RPO | Cost |
|---|---|---|---|
| Journal-based | Every write is journalled, then replayed at the peer | Near-continuous | A write amplification on every I/O at the primary |
| Snapshot-based | Periodic image snapshots, deltas shipped | The snapshot interval | No steady-state write penalty |
Journal-based mirroring makes every write on the primary cluster more expensive, permanently, in exchange for a very low RPO. That cost is paid by production, not by DR, and it is the factor most often left out of the decision.
PBS sync
Covered mechanically in DR for the backup server and offsite replication. Its place on these axes:
The slowest RPO and the only real history. An hourly sync means up to an hour of loss for a hardware event - worse than either alternative - and it is the only one of the three that can recover you from something that happened three weeks ago.
The cheapest bytes by a wide margin. Deduplication is global across the datastore, so a hundred guests built from the same template store the common chunks once. Compare a hundred full ZFS copies.
The slowest recovery. The guest must be restored, which means transferring its data before it can start. That is the RTO arithmetic from live restore, and live restore is what narrows the gap.
The only one that survives a compromise, when configured pull-direction
with remove-vanished off, because the DR copy is not reachable from the
primary.
What each does with a deletion
The single most useful way to compare them, because it is the failure people plan for least.
At 14:00, someone deletes the contents of a production filesystem.
| Mechanism | At 14:01 | At 20:00 | Recovery |
|---|---|---|---|
| ZFS replication, 15 min | Far copy still intact | Deletion replicated; earlier ZFS snapshots may remain | Roll back to a retained snapshot, if the retention covers it |
| RBD mirroring, journal | Deletion already at the far site | Same | None from this mechanism |
| PBS, nightly + hourly sync | Last night’s snapshot intact | Still intact | Restore, losing the day’s other work |
RBD mirroring’s row is not a defect. It is a correct description of a mechanism designed to keep two sites identical, applied to a failure where identical is the problem.
Combinations that actually work
The design rule: every named failure gets exactly one recovery path, and every mechanism is there because a specific failure names it.
Small estate, no shared storage
- Local ZFS +
pvesrto a second node, 15 minutes - covers node loss. - PBS nightly to a local datastore - covers deletion and corruption.
- PBS sync to an offsite datastore, pull direction - covers site loss and ransomware.
RPO: 15 minutes for hardware, 24 hours for everything else. RTO: minutes for node loss, hours for anything requiring a restore. This covers most small estates and is the cheapest complete answer.
Ceph cluster, single site
- Ceph replication across failure domains - covers disk, host and rack.
- PBS to a local datastore - covers deletion and corruption.
- PBS sync offsite, pull direction,
remove-vanishedoff - covers site loss.
RPO: zero for hardware inside the site, the backup interval for everything else. Note what is not here: no cross-site synchronous anything, because for almost every workload the honest requirement is “survive the site with a few hours of loss” and this meets it without a second Ceph cluster.
Two sites, seconds-scale RPO genuinely required
- Ceph at both sites, RBD mirroring between them - covers site loss with a seconds RPO.
- PBS at both sites, syncing - covers deletion, corruption and ransomware, which mirroring cannot.
- A documented promotion runbook, because promotion is a manual Ceph operation and the guest configurations do not mirror with the images.
This is a materially larger estate to run. Adopt it when a specific workload’s requirement names it, not as a general upgrade.
Knowledge check
Knowledge check · 5 questions
Q1. A site replicates with journal-based Ceph RBD mirroring, lag under ten seconds. At 14:00 an operator deletes a production filesystem’s contents. What is the state of the DR copy at 14:01?
Q2. A team takes nightly PBS backups and syncs them to the DR site hourly. They want a better RPO and increase the sync frequency to every 15 minutes. What changes?
Q3. Which statements about pvesr ZFS replication are accurate? Select all that apply.
Q4. Proxmox VE provides a management interface for Ceph RBD mirroring between clusters.
Q5. A ZFS pool is filling up but guest data has not grown. Which command is most likely to identify the cause?
Passing score: 75%. Answers are checked in this browser.