Skip to main content

Native HA Introduction

Native HA provides high availability for PostgreSQL using streaming replication without requiring external tools like Patroni or etcd. It's a lightweight HA solution suitable for simpler deployments.

How It Works

┌─────────────────┐      streaming       ┌─────────────────┐
│ PostgreSQL │◄────────────────────│ PostgreSQL │
│ Primary │────────────────────►│ Replica 1 │
│ (master) │ replication │ (standby) │
└─────────────────┘ └─────────────────┘
┌─────────────────┐
│ PostgreSQL │
│ Replica 2 │
│ (standby) │
└─────────────────┘
  • Primary: Accepts writes and streams WAL to replicas
  • Replicas: Receive WAL and replay it to stay in sync

Native HA vs Patroni

FeatureNative HAPatroni
External dependenciesNoneetcd, Consul, or ZooKeeper
Automatic failoverManualAutomatic
Cluster coordinationNoneDistributed
ComplexityLowMedium-High
Use caseSimple HA, read scalingMission-critical HA

When to Use Native HA

  • Use Native HA when:

    • You need simple primary-replica replication
    • You don't require automatic failover
    • You prefer to manage failover manually or via external scripts
    • You want a lightweight solution without external dependencies
  • Use Patroni when:

    • You need automatic failover
    • You have mission-critical workloads
    • You need distributed consensus for cluster state
    • You want DCS-backed cluster management

Environment Variables

Key environment variables for Native HA:

VariableDescriptionRequired
HA_MODESet to nativeYes
REPLICATION_ROLEprimary or replicaYes
REPLICATION_USERReplication userYes
REPLICATION_PASSWORDReplication passwordYes
PRIMARY_HOSTPrimary hostname (replicas only)Replica only

Default Replica Settings

Our container applies different defaults than vanilla PostgreSQL to ensure "works out of the box" behavior for read-heavy workloads.

Why We Change PostgreSQL Defaults

PostgreSQL defaults are conservative (designed for DBAs who want full control). In production read-scaling scenarios, many users expect replica queries to just work reliably without manual tuning.

Replica-Side Settings (Applied Automatically)

These are applied only when REPLICATION_ROLE=replica and do not affect the primary:

SettingPostgreSQL DefaultOur DefaultReason
hot_standby_feedbackoffonPrevents VACUUM from removing rows the replica needs
max_standby_streaming_delay30s-1 (infinite)Never cancel long queries due to WAL replay conflicts
max_standby_archive_delay30s-1 (infinite)Never cancel for archived WAL conflicts

Overriding Defaults

All settings can be overridden via environment variables:

# Example: Use stricter defaults instead of infinite
POSTGRESQL_CONFIG_MAX_STANDBY_STREAMING_DELAY: "60s"
POSTGRESQL_CONFIG_MAX_STANDBY_ARCHIVE_DELAY: "60s"

# Example: Disable hot_standby_feedback
POSTGRESQL_CONFIG_HOT_STANDBY_FEEDBACK: "off"

WAL Disk Monitoring

When using -1 (infinite) for standby delay settings, monitor the primary's WAL disk usage to ensure it doesn't grow unbounded if a replica falls behind or disconnects. Set up alerts on pg_wal directory size.

Next Steps