This episode moves the backup load to a replica: taking backups from the standby with pg1-standby and backup-standby to lighten the primary, maintaining WAL consistency, integrating with Patroni/repMgr, and restoring to a new node in an HA cluster. Backups and high availability work within a single architecture.

Up to episode 17, all our backups were taken from the primary — the server serving traffic. For large databases, backups consume CPU, I/O, and bandwidth — exactly the resources that production transactions need. In episode 18 we solve this problem elegantly: taking backups from the standby (replica) — a server that doesn't serve write traffic.
This is also the episode where pgBackRest and high availability (HA) meet: backups are no longer a burden on the primary, and restore becomes the way to grow new nodes in an HA cluster. Two systems usually managed separately now run as one.
The primary serves all writes and critical reads. Running backups there means:
A standby has none of these problems — it only applies WAL from the primary. Backup on a standby = zero load on the primary.
The standby must have streaming replication active from the primary, and the backup (full/diff/incr) stays consistent because it's taken from the same data files + WAL. pgBackRest ensures consistency by checking the WAL position during the backup — the same concept as a backup from the primary.
On the standby host, the stanza configuration points at the standby cluster:
[global]
repo1-path = /var/lib/pgbackrest
[main]
pg1-path = /var/lib/postgresql/16/standby
pg1-standby = ypg1-standby = y — tells pgBackRest that this cluster is a standby, so it handles the backup in the appropriate way.backup-standby = y option on the backup command:sudo -u postgres pgbackrest --stanza=main --backup-standby backup --type=fullA common question: how is a standby backup consistent if the standby's data files are always changing (applying WAL)?
The answer: pgBackRest records the WAL position (replay location) when the backup starts and finishes, then completes the backup with the WAL archived up to that position. The result is a standby backup identically consistent to a primary backup — both represent the database state at a certain point in time. This is why a restore from a standby backup is just as valid.
Note
A standby backup requires WAL archiving active on the primary (episode 6) — without archived WAL, standby backup consistency can't be guaranteed. Make sure archive_mode=on and archive_command point at the same repository.
Patroni and repMgr manage who becomes the primary and when failover happens. pgBackRest manages how data is recovered and how new nodes are born. The two complement each other: Patroni decides, pgBackRest provides the data.
The most common pattern in a Patroni-managed cluster:
backup-standby) — zero load on the primary.sudo -u postgres pgbackrest --stanza=main --delta restore
sudo -u postgres pg_ctl -D /var/lib/postgresql/16/main start
# Patroni detects the new node and connects it to the primaryBecause Patroni manages the cluster identity, make sure the pgBackRest stanza is consistent with the identity Patroni expects — restoring from the same backup then syncing via WAL is a very common pattern in production.
On failover, the standby becomes the primary. The consequences for pgBackRest:
archive_command is correct on all nodes, not just the old one.Best practice: run stanza-create and check on every node after failover so the cluster identity stays in sync:
sudo -u postgres pgbackrest --stanza=main check
sudo -u postgres pgbackrest --stanza=main infoWarning
After a failover, don't forget stanza-upgrade if the timeline changes drastically, and check on all nodes. The most common post-failover failure is WAL archiving still pointing at the old node — the failed_count alarm (episode 14) is usually the first to wake you up.
When an HA cluster needs an extra node (or a node fails), don't copy PGDATA from the primary (expensive and disruptive). Use a backup:
# 1. create the directory and restore from the last backup
sudo mkdir -p /var/lib/postgresql/16/main
sudo chown postgres:postgres /var/lib/postgresql/16/main
sudo -u postgres pgbackrest --stanza=main --delta restore
# 2. configure the replica (primary_conninfo) then start
# 3. Patroni/repMgr handles registration and streamingThe new node starts as a standby, applies WAL from the primary, and catches up quickly. A backup that was ever tested (episode 16) makes this process predictable.
Simulate adding a node in the lab:
sudo -u postgres pgbackrest --stanza=main --delta \
--pg1-path=/var/lib/postgresql/16/nodebaru restore
sudo -u postgres /usr/lib/postgresql/16/bin/pg_ctl \
-D /var/lib/postgresql/16/nodebaru start
# verify streaming: SELECT * FROM pg_stat_replication;Key takeaways:
backup-standby) moves the backup load from the primary to a replica.pg1-standby = y tells pgBackRest the cluster is a standby.check and stanza-upgrade on all nodes, and make sure archive_command is correct.In the next episode we'll measure and optimize for scale: large databases & delta optimization — parallel backup for terabyte data, tuning process-max to resources, --delta restore, and benchmarks comparing backup/restore duration against database size. Optimization starts from data, not guesses!