Home Database PostgreSQL High Availability: Patroni, repmgr, and Failover
Advanced 3 min · July 13, 2026

PostgreSQL High Availability: Patroni, repmgr, and Failover

Learn to build a production-grade PostgreSQL HA cluster using Patroni and repmgr.

N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Drawn from code that ran under real load.

Follow
Production
production tested
July 13, 2026
last updated
2,165
articles · all by Naren
Before you start⏱ 25-30 min read
  • Basic knowledge of PostgreSQL (installation, configuration, replication)
  • Familiarity with Linux command line and system administration
  • Understanding of distributed systems concepts (consensus, quorum)
  • Access to at least three servers or VMs for cluster setup
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Patroni uses distributed consensus (etcd/Consul) for automatic failover and cluster management.
  • repmgr is a simpler, standalone tool for replication management and manual failover.
  • Key HA components: replication, health checks, quorum, and fencing to prevent split-brain.
  • Production best practices: use synchronous replication for zero data loss, test failover regularly, and monitor replication lag.
✦ Definition~90s read
What is PostgreSQL High Availability?

PostgreSQL High Availability is a set of technologies and practices that ensure your PostgreSQL database remains accessible and operational despite node failures, using tools like Patroni or repmgr for automatic or manual failover.

Think of a PostgreSQL HA cluster like a relay race team.
Plain-English First

Think of a PostgreSQL HA cluster like a relay race team. The primary database is the lead runner, and replicas are backup runners. Patroni acts as the coach who watches the lead runner's health and instantly swaps in a backup if the lead falls. repmgr is like a manual substitution system where the coach decides when to swap. Both ensure the race (your application) continues without interruption.

In today's always-on world, database downtime can cost millions. PostgreSQL, while robust, is not immune to hardware failures, network partitions, or software crashes. High Availability (HA) ensures your database remains accessible even when a node fails. This tutorial dives into two popular PostgreSQL HA solutions: Patroni and repmgr. Patroni, built on distributed consensus (etcd, Consul, or Zookeeper), provides automatic failover and self-healing clusters. repmgr offers a simpler, more manual approach with robust replication management. We'll explore their architectures, setup, failover mechanics, and production pitfalls. By the end, you'll be able to design and operate a PostgreSQL cluster that survives node failures with minimal downtime. We'll also dissect a real-world outage caused by a misconfigured fencing mechanism, teaching you what not to do. Whether you're a DBA or a developer responsible for database reliability, this guide provides actionable insights for building resilient PostgreSQL deployments.

1. Understanding PostgreSQL High Availability Concepts

High Availability (HA) for PostgreSQL involves ensuring the database remains accessible despite node failures. Key concepts include: replication (streaming or logical), failover (automatic or manual), quorum (majority of nodes agree on primary), and fencing (isolating failed nodes to prevent split-brain). Patroni uses a distributed configuration store (etcd, Consul, Zookeeper) to maintain cluster state and elect a leader. repmgr relies on a dedicated monitoring database and manual or cron-driven failover. Both support synchronous and asynchronous replication. Synchronous replication guarantees zero data loss but impacts write performance. Asynchronous replication may lose some transactions during a crash but offers better performance. Understanding these trade-offs is crucial for designing an HA solution that meets your RPO (Recovery Point Objective) and RTO (Recovery Time Objective).

check_replication.sqlSQL
1
2
3
-- Check replication status on primary
SELECT client_addr, state, sync_state, write_lag, flush_lag, replay_lag
FROM pg_stat_replication;
Output
client_addr | state | sync_state | write_lag | flush_lag | replay_lag
-------------+-------+------------+-----------+-----------+------------
10.0.0.2 | streaming | sync | 0 | 0 | 0
10.0.0.3 | streaming | async | 5ms | 10ms | 15ms
🔥Synchronous vs Asynchronous
📊 Production Insight
In production, always have an odd number of etcd nodes (e.g., 3 or 5) to maintain quorum. A single etcd node is a single point of failure.
🎯 Key Takeaway
HA relies on replication, failover, quorum, and fencing. Choose synchronous replication for zero data loss at the cost of performance.

2. Setting Up Patroni with etcd

Patroni orchestrates PostgreSQL instances into a highly available cluster. It uses a distributed key-value store like etcd to store cluster state and leader election. To set up Patroni: install Patroni on each node, configure etcd, and create a Patroni configuration file (patroni.yml). The configuration defines the cluster name, PostgreSQL parameters, replication settings, and etcd endpoints. Patroni manages PostgreSQL via a REST API and automatically handles failover, replication, and recovery. Below is a minimal patroni.yml for a three-node cluster. After starting Patroni on each node, the cluster will elect a primary and replicas will stream from it.

patroni.ymlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
scope: mycluster
namespace: /db/
name: node1

restapi:
  listen: 0.0.0.0:8008
  connect_address: 10.0.0.1:8008

etcd:
  host: 10.0.0.10:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    postgresql:
      use_pg_rewind: true
      parameters:
        max_connections: 100
        wal_level: replica
        hot_standby: "on"
        wal_keep_segments: 8
        max_wal_senders: 5
        max_replication_slots: 5
        wal_log_hints: "on"

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 10.0.0.1:5432
  data_dir: /var/lib/pgsql/data
  bin_dir: /usr/pgsql/bin
  pgpass: /tmp/pgpass
  authentication:
    replication:
      username: replicator
      password: rep-pass
    superuser:
      username: postgres
      password: admin-pass
    rewind:
      username: rewind_user
      password: rewind-pass
  parameters:
    unix_socket_directories: /var/run/postgresql

tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  nosync: false
💡Patroni Configuration Best Practices
📊 Production Insight
Ensure etcd is deployed on separate nodes from PostgreSQL to avoid resource contention. Use TLS for etcd communication in production.
🎯 Key Takeaway
Patroni automates cluster management via etcd. The configuration file defines all aspects of the cluster, from replication to failover thresholds.

3. Managing Failover with Patroni

Patroni automatically handles failover when the primary becomes unreachable. It uses a leader election algorithm based on etcd's distributed locks. When the primary fails, Patroni on the replicas detect the loss of the leader lock and hold an election. The replica with the most recent WAL position becomes the new primary. You can also trigger manual failover using patronictl failover. Patroni supports switchover (planned failover) for maintenance. During failover, Patroni ensures that the old primary is fenced (e.g., via pg_ctl stop or hardware watchdog) before promoting a new primary to prevent split-brain. The failsafe_mode option can be enabled to require a majority of etcd nodes for promotion, adding an extra safety net.

failover_commands.shBASH
1
2
3
4
5
6
7
8
9
10
11
# List cluster members
patronictl -c /etc/patroni.yml list

# Manual failover to a specific candidate
patronictl -c /etc/patroni.yml failover --master node1 --candidate node2

# Planned switchover
patronictl -c /etc/patroni.yml switchover --master node1 --candidate node2

# Check cluster history
patronictl -c /etc/patroni.yml history
Output
+ Cluster: mycluster (6971234567890123456) +----+-----------+--------------+----------------------------------+---------+---------+
| Member | Host | Role | State | Lag | Tags |
+--------+-----------+--------------+----------------------------------+---------+---------+
| node1 | 10.0.0.1 | Replica | running | 0 | |
| node2 | 10.0.0.2 | Leader | running | | |
| node3 | 10.0.0.3 | Replica | running | 0 | |
+--------+-----------+--------------+----------------------------------+---------+---------+
⚠ Failover Testing
📊 Production Insight
Set ttl (time-to-live) appropriately. A short TTL (e.g., 30s) speeds up failover but may cause false positives during transient network issues. A longer TTL (e.g., 60s) is more stable but increases downtime.
🎯 Key Takeaway
Patroni automates failover using etcd-based leader election. Manual failover is also possible for planned maintenance.

4. Introduction to repmgr

repmgr (Replication Manager) is a simpler alternative to Patroni. It manages PostgreSQL replication and provides tools for monitoring, failover, and switchover. repmgr uses a dedicated database (repmgr metadata) to track cluster state. It supports both synchronous and asynchronous replication. Unlike Patroni, repmgr does not use distributed consensus; it relies on a single monitoring database. Failover can be manual or automated via cron jobs or event triggers. repmgr is easier to set up but lacks the automatic self-healing and quorum-based decisions of Patroni. It's suitable for smaller deployments or teams that prefer a more hands-on approach.

repmgr_register.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
-- Register a standby node with repmgr
SELECT repmgr_standby_register(
    node_name => 'node2',
    conninfo => 'host=10.0.0.2 port=5432 user=repmgr dbname=repmgr'
);

-- Check cluster status
SELECT * FROM repmgr.nodes;

-- Perform a failover (on the standby that should become primary)
SELECT repmgr_failover();
Output
node_id | upstream_node_id | node_name | type | active | priority | conninfo
---------+------------------+-----------+------+--------+----------+-----------------------------------------
1 | | node1 | primary | t | 100 | host=10.0.0.1 port=5432 user=repmgr ...
2 | 1 | node2 | standby | t | 100 | host=10.0.0.2 port=5432 user=repmgr ...
🔥repmgr vs Patroni
📊 Production Insight
repmgr's metadata database can become a single point of failure. Consider replicating it or using Patroni if you need higher availability.
🎯 Key Takeaway
repmgr is a lightweight replication manager that requires manual or cron-based failover. It's easier to set up but less automated than Patroni.

5. Fencing and Split-Brain Prevention

Fencing (also called STONITH - Shoot The Other Node In The Head) is critical to prevent split-brain scenarios where two nodes both think they are primary. In Patroni, fencing is achieved by using a watchdog device (e.g., Linux watchdog) or by issuing a pg_ctl stop command to the failed primary. repmgr relies on manual intervention or external fencing mechanisms. Without proper fencing, a network partition can lead to data corruption. Best practices: enable STONITH via hardware watchdog or IPMI, configure Patroni's failsafe_mode, and use synchronous replication to minimize data loss. Always test fencing by simulating network partitions.

watchdog_setup.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Install watchdog daemon
sudo yum install watchdog -y

# Configure watchdog to use hardware watchdog (e.g., /dev/watchdog)
echo "watchdog-device = /dev/watchdog" | sudo tee -a /etc/watchdog.conf
echo "watchdog-timeout = 10" | sudo tee -a /etc/watchdog.conf

# Start watchdog
sudo systemctl enable watchdog
sudo systemctl start watchdog

# In Patroni configuration, enable watchdog
tags:
  watchdog: true
⚠ Fencing is Mandatory
📊 Production Insight
In cloud environments, use cloud-specific fencing mechanisms (e.g., AWS EC2 API to stop instances) or rely on Patroni's failsafe_mode which requires etcd quorum for promotions.
🎯 Key Takeaway
Fencing prevents split-brain by ensuring a failed primary is isolated before promoting a new one. Use hardware watchdog or IPMI for reliable fencing.

6. Monitoring and Alerting for HA Clusters

Monitoring is essential for maintaining a healthy HA cluster. Key metrics to monitor: replication lag, cluster state (primary/replica), etcd health, and Patroni API status. Use tools like Prometheus with the postgres_exporter and Patroni exporter. Set up alerts for replication lag exceeding thresholds, node failures, and etcd leader changes. Patroni exposes a REST API at /cluster that returns JSON with cluster status. You can integrate this with your monitoring stack. repmgr provides command-line tools like repmgr cluster show and repmgr standby follow. Additionally, monitor PostgreSQL logs for errors related to replication or failover.

patroni_health_check.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Check Patroni cluster health via API
curl -s http://10.0.0.1:8008/cluster | jq .

# Example output
{
  "members": [
    {
      "name": "node1",
      "role": "leader",
      "state": "running",
      "api_url": "http://10.0.0.1:8008",
      "host": "10.0.0.1",
      "port": 5432,
      "timeline": 1
    },
    {
      "name": "node2",
      "role": "replica",
      "state": "running",
      "api_url": "http://10.0.0.2:8008",
      "host": "10.0.0.2",
      "port": 5432,
      "timeline": 1,
      "lag": 0
    }
  ]
}
💡Alerting Thresholds
📊 Production Insight
In addition to monitoring, implement automated recovery scripts that can restart failed Patroni processes or reinitialize replicas if they fall too far behind.
🎯 Key Takeaway
Monitor replication lag, cluster state, and etcd health. Use Patroni's REST API for easy integration with monitoring tools.

7. Zero-Downtime Upgrades and Maintenance

One of the benefits of HA is the ability to perform upgrades without downtime. For PostgreSQL minor version upgrades, you can use a rolling upgrade: failover to a replica, upgrade the old primary, then fail back. For major version upgrades, use logical replication or tools like pg_upgrade with Patroni's switchover. Patroni supports switchover for planned role changes. repmgr also provides repmgr standby switchover. Always test upgrades in a staging environment. During maintenance, ensure that the application connection strings are updated to point to the new primary if using a connection pooler like PgBouncer or HAProxy.

rolling_upgrade.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
# Perform a rolling upgrade of PostgreSQL minor version
# 1. Switchover to replica (node2)
patronictl -c /etc/patroni.yml switchover --master node1 --candidate node2

# 2. Upgrade node1 (old primary) to new version
sudo yum update postgresql*
sudo systemctl restart postgresql

# 3. Wait for node1 to rejoin as replica
patronictl -c /etc/patroni.yml list

# 4. Switch back if desired
patronictl -c /etc/patroni.yml switchover --master node2 --candidate node1
🔥Connection Draining
📊 Production Insight
For major version upgrades, consider using logical replication to avoid downtime entirely. Tools like pglogical can replicate data between different PostgreSQL versions.
🎯 Key Takeaway
Use switchover for zero-downtime upgrades. Always test the upgrade process in a non-production environment first.
● Production incidentPOST-MORTEMseverity: high

The Split-Brain Nightmare: A Fencing Failure

Symptom
Application reported 'connection refused' and 'duplicate primary' errors. Two nodes both believed they were the primary.
Assumption
The DBA assumed Patroni's automatic failover would handle a network partition gracefully.
Root cause
Fencing (STONITH) was disabled in the cluster configuration. When the primary lost connectivity to etcd, Patroni promoted a replica, but the old primary continued serving writes, causing split-brain.
Fix
Enabled STONITH via a hardware watchdog and configured Patroni to use remove_data_after_initdb to clean up the old primary's data. Also added failsafe_mode to prevent promotion without quorum.
Key lesson
  • Always enable fencing (STONITH) in production clusters.
  • Test network partition scenarios regularly.
  • Use synchronous replication to minimize data loss during failover.
  • Monitor etcd cluster health as it's the single point of failure for Patroni.
  • Document and practice failover procedures.
Production debug guideSymptom to Action4 entries
Symptom · 01
Application gets 'connection refused' to primary
Fix
Check Patroni member status: patronictl list. If primary is down, verify etcd health and trigger manual failover if needed.
Symptom · 02
Replication lag is increasing
Fix
Check pg_stat_replication on primary. Ensure network bandwidth and replica resources are adequate. Consider using synchronous replication.
Symptom · 03
Split-brain detected (two primaries)
Fix
Immediately stop writes on one primary using pg_ctl stop -m fast. Use patronictl remove to clean up the rogue node. Investigate fencing configuration.
Symptom · 04
Failover not triggering automatically
Fix
Check Patroni logs and etcd connectivity. Verify ttl and loop_wait settings. Ensure the replica is in streaming replication mode.
★ Quick Debug Cheat SheetOne-line commands for common HA issues
Primary is down, no failover
Immediate action
Check Patroni status
Commands
patronictl -c /etc/patroni.yml list
patronictl -c /etc/patroni.yml failover --master <old_primary> --candidate <new_primary>
Fix now
Manually trigger failover if automatic failed.
Replica not replicating+
Immediate action
Check replication state
Commands
SELECT * FROM pg_stat_replication;
SELECT pg_wal_replay_resume();
Fix now
Restart replica or reinitialize from primary.
Split-brain detected+
Immediate action
Stop the rogue primary
Commands
pg_ctl -D /var/lib/pgsql/data stop -m fast
patronictl remove <cluster_name> --force
Fix now
Demote the rogue node and rejoin as replica.
FeaturePatronirepmgr
Automatic FailoverYes (via etcd consensus)No (manual or cron)
Fencing SupportBuilt-in (watchdog, failsafe_mode)External (manual)
Configuration Storeetcd/Consul/ZookeeperPostgreSQL metadata database
ComplexityHighLow
Self-HealingYesNo
Suitable ForLarge, mission-critical clustersSmall to medium deployments
⚙ Quick Reference
7 commands from this guide
FileCommand / CodePurpose
check_replication.sqlSELECT client_addr, state, sync_state, write_lag, flush_lag, replay_lag1. Understanding PostgreSQL High Availability Concepts
patroni.ymlscope: mycluster2. Setting Up Patroni with etcd
failover_commands.shpatronictl -c /etc/patroni.yml list3. Managing Failover with Patroni
repmgr_register.sqlSELECT repmgr_standby_register(4. Introduction to repmgr
watchdog_setup.shsudo yum install watchdog -y5. Fencing and Split-Brain Prevention
patroni_health_check.shcurl -s http://10.0.0.1:8008/cluster | jq .6. Monitoring and Alerting for HA Clusters
rolling_upgrade.shpatronictl -c /etc/patroni.yml switchover --master node1 --candidate node27. Zero-Downtime Upgrades and Maintenance

Key takeaways

1
Patroni provides automatic failover using distributed consensus; repmgr offers a simpler manual approach.
2
Fencing (STONITH) is critical to prevent split-brain and data corruption.
3
Monitor replication lag, cluster state, and etcd health with alerting.
4
Test failover and upgrade procedures regularly in a staging environment.
5
Use synchronous replication for zero data loss, but be aware of performance trade-offs.

Common mistakes to avoid

3 patterns
×

Disabling fencing in Patroni to avoid complexity.

×

Using an even number of etcd nodes.

×

Not testing failover scenarios regularly.

INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
Explain how Patroni achieves high availability for PostgreSQL.
Q02SENIOR
What is split-brain and how do you prevent it in a PostgreSQL HA cluster...
Q03SENIOR
Compare Patroni and repmgr for PostgreSQL replication management.
Q01 of 03SENIOR

Explain how Patroni achieves high availability for PostgreSQL.

ANSWER
Patroni uses a distributed configuration store (etcd) to maintain cluster state and leader election. It monitors PostgreSQL health via a REST API and automatically promotes a replica to primary if the current primary fails. It also handles replication setup and reconfiguration.
FAQ · 5 QUESTIONS

Frequently Asked Questions

01
What is the difference between Patroni and repmgr?
02
How do I prevent split-brain in PostgreSQL HA?
03
Can I use Patroni with cloud-managed PostgreSQL?
04
What is the recommended number of etcd nodes?
05
How do I monitor replication lag in Patroni?
N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Drawn from code that ran under real load.

Follow
Verified
production tested
July 13, 2026
last updated
2,165
articles · all by Naren
🔥

That's MySQL & PostgreSQL. Mark it forged?

3 min read · try the examples if you haven't

Previous
MySQL InnoDB Cluster: High Availability Setup
15 / 20 · MySQL & PostgreSQL
Next
pgvector: Vector Search and Embeddings in PostgreSQL