Skip to content

C15 — Replication Health

Streaming (physical) replication health from the receiving side: how stale the WAL receiver's last message is, inactive physical replication slots, and query conflicts on a standby (queries cancelled because they held a snapshot the primary needed to reclaim). A small category by design — most of replication's own health signal lives in categories 09 and 12; this one covers what's specific to a plain physical standby.

3 checks, PGHF15-001 through PGHF15-003. Every check here is PGHF-namespace and built-in — see Metadata Columns Explained for what each field below actually means, and Resetting to Defaults for why these definitions can't be hand-edited in place.

PGHF15-001 — WAL receiver last-message age

Standby only.

A standby without an active WAL receiver isn't replicating and falls further behind every second until it reconnects — this can happen silently, with no error raised anywhere, until someone notices the standby is stale.

How to fix

  1. Check the standby's log for the WAL receiver's disconnect reason — a network issue, an authentication failure, or the primary having recycled WAL the standby still needed (PGHF09-007/wal_keep_size/a missing slot).
  2. Confirm primary_conninfo in the standby's config still points at a reachable primary.
  3. If WAL the standby needs is already gone from the primary, a full resync (fresh base backup) is required — the connection alone won't fix a gap that large.

PGHF15-002 — Inactive physical replication slots

Primary only.

An inactive physical slot means its standby has disconnected, yet the slot itself keeps retaining WAL indefinitely — the physical-replication counterpart to PGHF09-001/PGHF09-011's logical-slot version of the same disk-exhaustion risk.

How to fix

See PGHF09-001's remediation — drop the slot if its standby is genuinely decommissioned:

SELECT pg_drop_replication_slot('the_slot_name');

or fix the standby's connection if it should still be active. Don't leave an inactive slot around "just in case" — it retains WAL unboundedly the entire time.

PGHF15-003 — Standby query conflicts by type

Different conflict types (snapshot, lock, bufferpin, deadlock, logical slot) call for different fixes — a breakdown by type turns PGHF13-006's raw conflict count into an actionable direction for tuning hot_standby_feedback or max_standby_streaming_delay.

How to fix

Match the fix to the dominant conflict type in the breakdown:

  • snapshot/bufferpin/lock conflicts: hot_standby_feedback = on on the standby (PGHF12-010) is the primary lever — it tells the primary not to remove row versions the standby might still need.
  • deadlock conflicts: usually resolve on their own via retry; frequent occurrences point at genuine standby query concurrency worth investigating separately.
  • logical slot conflicts: check that hot_standby_feedback is on and that the standby has enough max_slot_wal_keep_size headroom (PGHF09-010) for its logical consumers.

If conflicts remain frequent even with feedback on, raise max_standby_streaming_delay to give the standby more slack before PostgreSQL cancels a conflicting query.

Continue to Reading the Catalog Without Table Access.