HA Basics
High availability for PostgreSQL means surviving primary loss with a defined recovery time (RTO) and acceptable data loss window (RPO). Apps must reconnect and retry through the failover window.
Search across all documentation pages
High availability for PostgreSQL means surviving primary loss with a defined recovery time (RTO) and acceptable data loss window (RPO). Apps must reconnect and retry through the failover window.
Tier-0 OLTP target: 99.95% uptime, RTO < 60s, RPO < 30s with async physical standby + Patroni 3.x.
-- Verify standby is ready for promotion
SELECT pg_is_in_recovery(), pg_last_wal_replay_lsn(), now() - pg_last_xact_replay_timestamp() AS replay_delay;# App connection string: target primary via proxy, not bare node IP
# postgresql://app:***@pg-primary.internal:5432/appdb?connect_timeout=5&application_name=checkoutWhen to reach for this: Any production database where minutes of write outage directly hits revenue or SLA credits.
Define SLOs, measure failover budget, configure client retry:
-- On standby: replay freshness before drill
SELECT CASE
WHEN pg_last_xact_replay_timestamp() IS NULL THEN 'no replay yet'
ELSE (now() - pg_last_xact_replay_timestamp())::text
END AS replay_age;# Patroni 3.x: check cluster leader (from ops host)
curl -s http://patroni-node1:8008/cluster | jq '.members[] | {name, role, state}'# Application retry pattern (psycopg) - simplified
import time
import psycopg
for attempt in range(5):
try:
with psycopg.connect(conninfo, connect_timeout=5) as conn:
conn.execute("SELECT 1")
break
except psycopg.OperationalError:
time.sleep(2 ** attempt)What this demonstrates:
| Metric | Meaning | Who owns |
|---|---|---|
| RTO | Max acceptable downtime | Product + SRE |
| RPO | Max acceptable data loss | Product + DBA |
| MTTR | Mean time to restore service | Ops runbooks |
| Error budget | Allowed monthly downtime | SLO doc |
| Layer | Component | Failover role |
|---|---|---|
| Data | Physical streaming standby | Promotable copy |
| Orchestration | Patroni 3.x + etcd/Consul | Leader election |
| Routing | HAProxy / VIP / cloud LB | Stable connection target |
| Pooling | PgBouncer 1.x | Reconnect after backend change |
| Client | App driver retry | Absorb brief unavailability |
99.9% allows ~43 minutes downtime per month. 99.95% allows ~22 minutes. Failover drills must prove you stay inside the budget including app cold start.
57P01 / connection reset - Brief blip becomes user-visible outage. Fix: Retry transient errors for idempotent reads and safe writes.server_lifetime + health checks; pause/resume during failover.| Alternative | Use When | Don't Use When |
|---|---|---|
| Single primary + fast PITR restore | Dev / non-critical | Tier-0 revenue path |
| Managed multi-AZ (RDS, Cloud SQL) | Small ops team | Custom Patroni required |
| Sync replication | Zero RPO for commits | WAN latency unacceptable |
Replication provides a standby; HA requires automatic failover, routing, and app behavior.
Often 15-60 seconds for detection plus promotion plus proxy update. Measure in drills.
PgBouncer pools connections; it does not elect leaders. Pair with Patroni and HAProxy.
Read replicas improve scale; HA failover target is a physical standby in sync with promotion policy.
Automated Patroni promotion may not page anyone. Alert on leader change and failed health checks.
Stack versions: This page was written for PostgreSQL 18.4 (stable 18, maintenance 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, and PostGIS 3.5+.
Reviewed by Chris St. John·Last updated Jul 18, 2026