# hot_standby_feedback

> hot_standby_feedback — Allows feedback from a hot standby to the primary that will avoid query conflicts. Observed in PG9.1–19 Beta 3; its last measured boot default is off in PG19 Beta 3, with sighup context. This is a beta-snapshot fact and can change before PostgreSQL 19 GA.
---

> [!NOTE]
> **Fact — official short description:** “Allows feedback from a hot standby to the primary that will avoid query conflicts.”

## Identity {#identity}

| Field | Value | Meaning |
| --- | --- | --- |
| Type | `bool` | Upstream pg_settings type |
| Context | `sighup` | Takes effect after configuration reload |
| Unit | — | Raw unit |
| Range | — | Raw limits in the last observed version |
| Enum values | — | — for non-enum types |
| Category | Replication / Standby Servers | Upstream classification |
| Latest boot value | `off` | off |
{.fields meta="-"}

## Lifecycle {#lifecycle}

| Fact | Value |
| --- | --- |
| First observed | PG9.1 |
| Present in | PG9.1–19 Beta 3 |
| Removed in | No |
| Introduction commit | [`bca8b7f16a3e`](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=bca8b7f16a3e720794cb0afbdb3733be4f8d9c2c) — Hot Standby feedback for avoidance of cleanup conflicts on standby. Standby optionally sends back information about oldestXmin of queries which is then checked and applied to the WALSender's proc->xmin. GetOldestXmin() is modified slightly to agree with GetSnapshotData(), so that all backends on primary include WALSender within their snapshots. Note this does nothing to change the snapshot xmin on either master or standby. Feedback piggybacks on the standby reply message. vacuum_defer_cleanup_age is no longer used on standby, though parameter still exists on primary, since some use cases still exist. |
| Commit date | 2011-02-16 |
| Discussion | — |

## Default history {#default-history}

| Versions | Raw `boot_val` | Unit | Human value |
| --- | --- | --- | --- |
| PG9.1–19 Beta 3 | `off` | — | off |
{.full-width caption="Measured PG9.0–19 Beta 3 boot defaults"}

## How it works {#mechanism}

A standby with feedback enabled reports information about snapshots needed by its running queries to the primary or upstream standby. The upstream can then avoid vacuum cleanup that would remove row versions still visible to those queries. Messages are not sent more frequently than wal_receiver_status_interval.

Avoiding cleanup conflicts transfers the cost to the primary: dead row versions can remain longer, increasing table and index bloat and vacuum work. In cascading replication feedback is passed upstream, so one old snapshot far downstream can affect the primary.

The mechanism addresses cleanup-record conflicts, not every hot-standby conflict. DDL locks, dropped objects, tablespace actions, and some page-level conflicts can still cancel queries. Feedback also has gaps while a non-slot standby is disconnected, and clock changes can disturb its timing.

## Tuning advice {#tuning-advice}

> [!TIP]
> **Advice.** These are workload-specific starting points and must be validated with measurements.

| Workload | Guidance |
| --- | --- |
| OLTP | Enable it only when reducing standby query cancellation is worth possible primary bloat. Bound standby query duration, monitor transaction age, dead tuples, table growth, vacuum progress, and pg_stat_database_conflicts; an HA-only standby often benefits more from timely replay than long query survival. |
| OLAP | It is useful for reporting standbys with long reads, but pair it with workload timeouts and a bloat budget on the primary. Consider a dedicated reporting topology if analytical snapshots routinely block cleanup for hours. |
| Small nodes | Start from off unless cancellations are a demonstrated problem. Limited storage makes primary bloat especially risky; if enabled, use short query limits and aggressive monitoring. |
{.full-width}

## Pigsty {#pigsty}

Values use the fixed 8-vCPU, 32-GiB, 100-GiB SSD fixture and render the current Pigsty templates for PG19 Beta 3; this does not assert current Pigsty support for that historical or beta release.

| Template | Effective value | Versus upstream boot | Source expression |
| --- | --- | --- | --- |
| OLTP | `on` | different | `'on'` |
| OLAP | `on` | different | `'on'` |
| CRIT | `on` | different | `'on'` |
| TINY | `on` | different | `'on'` |
{.full-width}

> [!CAUTION]
> **Advice — pending human review.** Fact from the current Pigsty template projection: OLTP: PG9.1–19 Beta 3 = on (dcs); OLAP: PG9.1–19 Beta 3 = on (dcs); CRIT: PG9.1–19 Beta 3 = on (dcs); TINY: PG9.1–19 Beta 3 = on (dcs). Advice, pending human review — confirm the operational intent against the current Pigsty templates and supported PostgreSQL versions before publication.

## Common pitfalls {#common-pitfalls}

- Enabling it and ignoring table or index bloat on the primary.
- Expecting it to prevent DDL, lock, database-drop, or tablespace conflicts.
- Allowing an unbounded long query on a downstream standby to hold back cleanup upstream.
- Assuming feedback remains effective while a slotless standby is disconnected.
- Ignoring clock jumps and wal_receiver_status_interval when reasoning about feedback timing.

## Related parameters {#related-parameters}

[`max_standby_streaming_delay`](/parameters/max-standby-streaming-delay/) · [`max_standby_archive_delay`](/parameters/max-standby-archive-delay/) · [`wal_receiver_status_interval`](/parameters/wal-receiver-status-interval/) · [`primary_slot_name`](/parameters/primary-slot-name/) · [`autovacuum_vacuum_scale_factor`](/parameters/autovacuum-vacuum-scale-factor/) · [`log_recovery_conflict_waits`](/parameters/log-recovery-conflict-waits/)

## References {#references}

- [PostgreSQL 19 Beta 3 — hot_standby_feedback](https://www.postgresql.org/docs/19/runtime-config-replication.html#GUC-HOT-STANDBY-FEEDBACK)
- [PostgreSQL 18: Handling Hot Standby Query Conflicts](https://www.postgresql.org/docs/18/hot-standby.html#HOT-STANDBY-CONFLICT)
- [PostgreSQL 18: Replication Slots](https://www.postgresql.org/docs/18/warm-standby.html#STREAMING-REPLICATION-SLOTS)
- [PostgreSQL 19 release notes](https://www.postgresql.org/docs/19/release-19.html)
- [Machine-readable GUC export](/data/guc.jsonl)
