PostgreSQL HA: Patroni, repmgr and pgpool, compared honestly
These three tools are frequently compared as if they solve the same problem. They do not. One manages cluster state, one manages replication, and one is a router that people mistake for a failover mechanism.
Choosing a PostgreSQL HA stack is difficult mostly because the tools are described in marketing language that makes them sound interchangeable. They are not interchangeable. Understanding what each one actually is makes the choice straightforward in most environments.
What each tool actually is
repmgr is replication management plus a failover command. It extends PostgreSQL’s native streaming replication with tooling to promote a standby, and it uses a witness node to avoid split brain. It has no opinion about where clients connect.
Patroni is a cluster state manager built on a distributed consensus store — etcd, Consul or ZooKeeper. It decides who is primary, runs the promotion, and rewrites configuration. It can also manage a HAProxy or a connection pooler, and it does its own leader election rather than relying on a witness quorum.
pgpool-II is a connection pooler and query router with a health-check facility. It sits in front of the database and can direct writes to the primary. It is often deployed as if it were the HA mechanism, and that is where most of the confusion comes from.
The distinction that matters
Patroni and repmgr answer the question: which node is primary, and how do we agree on it?
pgpool answers the question: where should this connection go right now?
Those are different problems, and neither tool solves the other’s. A pgpool that promotes a standby without a consensus mechanism is a router making a decision it is not equipped to make — and two pgpools disagreeing about who is primary is a split-brain generator, not a high availability system.
Where each one fits
repmgr is usually right when you are migrating off manual streaming replication, you have a small number of nodes, you want minimal additional infrastructure, and your team already understands PostgreSQL internals. It is the smallest step from a hand-built setup.
Patroni is usually right when you want automated failure detection and promotion without a human in the loop, you can run and monitor a consensus cluster, and you need the primary decision to be made by something quorum-based rather than by a single witness. The etcd cluster becomes part of your critical path, and you have to operate it accordingly — that is the real cost, and it is worth stating plainly.
pgpool is usually right when you need connection pooling and read/write splitting. Combine it with Patroni or repmgr for the failover decision, and make sure pgpool is not the thing deciding who is primary.
The parts everyone gets wrong
The application has to reconnect. This is the most common cause of a “successful” failover that still produces an outage. The database failed over in eight seconds; the connection pool kept serving dead connections for ninety more. Test the failure with the application connected and measure the interruption the user experiences, not the one the database reports.
Fencing has to exist. In a two-node setup, a witness is not optional. Without one, the surviving node cannot distinguish “my peer is down” from “my network to my peer is down”, and acting on that ambiguity is how you lose data.
Replication lag is a data loss budget. Synchronous commit is slower and safer; asynchronous is faster and loses whatever was in flight. The choice is a business decision disguised as a configuration parameter, and whoever is on call during the incident should not be the one making it for the first time.
Fail-back is a separate procedure. Everyone rehearses failover. Far fewer rehearse returning to the original topology, which often requires a rebuild of the demoted node rather than a simple rejoin.
How to decide in an afternoon
Write down three things:
- What interruption can the business accept? Not the aspiration — the number the CFO would recognise as a problem.
- What data loss can it accept? This directly determines the commit mode and whether you need a synchronous standby.
- Who operates the consensus layer? If the answer is nobody, that is a reason to prefer the simpler option rather than to bolt on a system nobody will watch.
Most of the time, those three answers pick the tool for you. The mistake is choosing by popularity and then discovering the operational cost of the consensus cluster in month three, when the person who set it up has moved to a different project.