PostgreSQL

PostgreSQL Streaming Replication: Zero to Production

Rakesh Mamidala·Founder & Lead Engineer··8 min read

The Foundation Under Everything

Read replicas, automatic failover, near-zero-downtime maintenance — every PostgreSQL HA story sits on streaming replication. The primary ships its write-ahead log to one or more standbys in real time; each standby is a byte-exact, read-only hot standby that can also serve read queries. Get this right and the rest (like Patroni) is automation on top.

On the primary

ini
# postgresql.conf
wal_level = replica
max_wal_senders = 10
# a dedicated role for the standby to connect with
#   CREATE ROLE replica WITH REPLICATION LOGIN PASSWORD '…';
# pg_hba.conf: allow the replica host to connect for 'replication'

Seeding the standby

A standby starts as a physical copy of the primary, taken with pg_basebackup, plus a standby.signal file that tells PostgreSQL to boot in standby mode and stream:

bash
pg_basebackup -h primary-host -U replica -D /var/lib/pgsql/data \
  -Fp -Xs -P -R
# -R writes standby.signal + primary_conninfo automatically.
# Start PostgreSQL — it connects and begins streaming WAL.

Replication slots: don’t skip these

Without a slot, a primary can recycle WAL a lagging or briefly-offline standby still needs — breaking replication and forcing a re-clone. A replication slot makes the primary retain WAL until the standby has consumed it. (The flip side: a dead standby with a slot will make WAL pile up on the primary, so monitor it.)

sql
-- on the primary
SELECT pg_create_physical_replication_slot('standby1');
-- reference it via primary_slot_name = 'standby1' on the standby

Async vs sync

Asynchronous (the default) is fast — the primary doesn’t wait for the standby — but a failover can lose the last in-flight transactions. Synchronous (synchronous_standby_names + synchronous_commit = on) makes a commit wait until a standby has the data: zero data loss, higher commit latency. Choose per your durability needs; many run async replicas plus one sync standby.

Monitoring lag

sql
-- on the primary: one row per connected standby
SELECT client_addr, state,
       pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS bytes_behind
FROM pg_stat_replication;

Physical streaming replication gives you read-scaling and a hot standby; it does not give you automatic failover — that’s the orchestration layer’s job. And it’s distinct from logical replication: physical copies the whole cluster byte-for-byte to a read-only standby; logical streams selected rows to a writable target. Physical for HA; logical for migrations.

The Data Guard standby you already know

For Oracle DBAs, streaming replication is the physical-standby story from Data Guard. Get your data onto PostgreSQL first with DBMigrateAIPro — validated, provable, free for Year 1.