What Is a Highly Available PostgreSQL Cluster?

An HA (High Availability) PostgreSQL Cluster is a piece of highly dedicated performance infrastructure that uses multiple database servers instead of a single instance. This approach is designed to keep the database systems available even during potential failures.

High availability refers to one server that acts as the primary instance, which handles the write requests, while the other Patroni nodes maintain copies through streaming replication.

PostgreSQL server cluster

See Also: How to Set Up a PostgreSQL Database Cluster

Patroni manages the cluster topology and failover process, while an etcd cluster works as a distributed configuration store. These high-availability (HA clusters can reduce downtime dramatically by offering a healthy replica ready to become the new current primary when the main fails. For all of this to work, there is a load balancer in place that routes SQL queries and database connections to the correct PostgreSQL instance, helping remove a single point of failure.

Note: High availability is measured by uptime defined in SLAs. This zero-downtime maintenance allows upgrades and patches to be applied to standby nodes first.

How Patroni and etcd Provide PostgreSQL High Availability

Put simply, Patroni manages the Patroni processes and simultaneously coordinates with the PostgreSQL failover system across multiple Patroni nodes. It works by constantly monitoring the primary instance, managing the leader lock, and promoting a healthy replica.

Patroni also exposes a Patroni REST API for cluster monitoring and rest api communication.

In turn, the etcd cluster stores the shared cluster state needed for Patroni to be able to easily coordinate the failover process. Together, Patroni and etcdprovide very high availability by tracking the leader node, maintaining the cluster topology, and helping ensure applications connect to a healthy database instance.

Note: Recovery time objective (RTO) defines how quickly services must be restored, while the recovery point objective (RPO) indicates acceptable data loss after an incident.

How to Deploy a Highly Available PostgreSQL Cluster

To begin with, we have designed a step-by-step guide for deploying a highly available PostgreSQL (3-node) cluster. In our case, Patroni will manage failover and state, while etcd will provide the distributed setup we need to store the high availability configuration.

The examples use Debian 12 or 13 with private IP addresses. Don’t forget to always replace the example hostnames and IPs with those from your environment.

⚠️You need sudo privileges!

Step 1: Prepare the PostgreSQL Servers

The first step is preparing the three Debian instances.

So, the best advice here is to keep the OS, system time, hardware resources, and networking the same across all servers. This is easy to manipulate if you are using a cloud infrastructure, but if you’re locked into certain hardware capabilities on a dedicated setup, you may continue without tweaking the servers.

Here is our example cluster:

  • pg1: 10.0.0.11
  • pg2: 10.0.0.12
  • pg3: 10.0.0.13

The first thing to do is update the system and install basic utilities:

sudo apt update 
sudo apt upgrade -y 
sudo apt install -y curl vim chrony 
sudo systemctl enable --now chrony

Also, verify the hostname, network connectivity, and available storage:

hostnamectl 
ping -c 3 10.0.0.12 
ping -c 3 10.0.0.13 
df -h 
free -h

For a general-purpose three-node PostgreSQL HA cluster, each node should have at least 8 dedicated CPU cores, 32 GB RAM, and 500 GB of enterprise SSD or NVMe storage.

Note: Limiting PostgreSQL resources under heavy workloads reduces memory usage, but strict memory conditions still require monitoring. If a server runs into memory pressure, check memoryerror kernel logs alongside PostgreSQL and system logs.

Step 2: Install and Configure etcd

Since Patroni uses etcd to store cluster state and coordinate leader elections, we are going to proceed with installing it. Using three etcd members provides redundancy and prevents a single etcd server from becoming a coordination bottleneck.

Here’s how to install etcd on all three Debian servers:

ETCD_VER=v3.7.0 
cd /tmp

curl -LO https://github.com/etcd-io/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz tar xzf etcd-${ETCD_VER}-linux-amd64.tar.gz 

sudo mv etcd-${ETCD_VER}-linux-amd64/etcd /usr/local/bin/ 
sudo mv etcd-${ETCD_VER}-linux-amd64/etcdctl /usr/local/bin/

Then you need to create the etcd user and required directories:

sudo useradd --system --home /var/lib/etcd --shell /usr/sbin/nologin etcd 
sudo mkdir -p /etc/etcd /var/lib/etcd 
sudo chown -R etcd:etcd /var/lib/etcd

The most important part is to create /etc/etcd/etcd.yml on each server. Don’t forget to change the name and the IP addresses for each node:

name: etcd1 
data-dir: /var/lib/etcd 

listen-client-urls: http://10.0.0.11:2379 
advertise-client-urls: http://10.0.0.11:2379 

listen-peer-urls: http://10.0.0.11:2380 
initial-advertise-peer-urls: http://10.0.0.11:2380 

initial-cluster: etcd1=http://10.0.0.11:2380,etcd2=http://10.0.0.12:2380,etcd3=http://10.0.0.13:2380 initial-cluster-token: postgresql-ha 
initial-cluster-state: new

Finally, create the systemd service:

[Unit] 
Description=etcd 
After=network-online.target

[Service] 
User=etcd 
ExecStart=/usr/local/bin/etcd --config-file=/etc/etcd/etcd.yml 
Restart=on-failure

[Install] 
WantedBy=multi-user.target

We also recommend saving it as /etc/systemd/system/etcd.service, then start etcd:

sudo systemctl daemon-reload 
sudo systemctl enable --now etcd

All three endpoints should return a healthy status. At this point, the etcd cluster is ready for Patroni, and the next step is installing and configuring PostgreSQL for replication.

Step 3: Install and Configure PostgreSQL

PostgreSQL supports streaming and logical replication methods:

  • Logical replication allows fully selective table replication from primary to standby.
  • PostgreSQL streaming replication uses Write-Ahead Logs (WAL) for data transfer.

For this cluster, use streaming replication because Patroni relies on physical replication between PostgreSQL nodes. Here’s how to install PostgreSQL on all three Debian servers:

sudo apt update 
sudo apt install -y postgresql

Then, on pg1, create the replication user:

sudo -u postgres psql
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'StrongReplicationPassword';

Then edit postgresql.conf on pg1:

wal_level = replica 
max_wal_senders = 10 
max_replication_slots = 10

Add the other nodes to pg_hba.conf:

host replication replicator 10.0.0.12/32 scram-sha-256 
host replication replicator 10.0.0.13/32 scram-sha-256

When ready, we recommend restarting PostgreSQL.

Also, keep PostgreSQL focused on database workloads and avoid running unnecessary asynchronous tasks or other databases on the same node when resources are limited. This leaves more CPU and memory available for the PostgreSQL cluster.

Note: It’s important to note that Patroni supports PostgreSQL versions 9.3 to 18, and Patroni can run natively on Kubernetes environments.

Step 4: Install and Configure Patroni

So, Patroni manages the PostgreSQL cluster, monitors node health, and coordinates automatic failover. Patroni requires a PostgreSQL Python driver for operation. A minimal Patroni cluster can be started with YAML configuration files. To begin with, you need to install Patroni and its PostgreSQL driver on all three Debian servers. Here’s a straightforward step-by-step guide:

sudo apt update 
sudo apt install -y patroni python3-psycopg2

Create the Patroni configuration directory:

sudo mkdir -p /etc/patroni

Create /etc/patroni/patroni.yml and define the cluster name, etcd endpoints, PostgreSQL settings, and Patroni configuration parameters:

scope: postgres-ha 
name: pg1

etcd:

hosts: 10.0.0.11:2379,10.0.0.12:2379,10.0.0.13:2379

postgresql:

listen: 0.0.0.0:5432 
connect_address: 10.0.0.11:5432 
data_dir: /var/lib/postgresql/17/main 
authentication: 
	superuser: 
		username: postgres 
		password: StrongPostgresPassword 
	replication: 
		username: replicator 
		password: StrongReplicationPassword

Also, for additional protection against node failures, you can configure Patroni to activate Linux watchdog device support. The Linux watchdog device helps restart an unresponsive node, adding another layer of protection to the failover process.

⚠️Reminder: Don’t forget to change name, connect_address, and data_dir as needed for each node.

Step 5: Start the PostgreSQL Cluster

We have now configured the Postgres database using Patroni, so it can start managing the replication process, the state of the cluster, and the failover mechanism. The Patroni setup is controlled through the patroni.yml file, while settings stored in etcd apply across the cluster.

We start Patroni with the yml file:

sudo patroni /etc/patroni/patroni.yml

Once started, Patroni initializes PostgreSQL and determines which node becomes the leader. You can check the cluster through the Patroni rest api:

curl http://10.0.0.11:8008/patroni

The API returns the status of the Patroni instance, including its PostgreSQL state and role. Patroni’s REST API also provides endpoints for cluster status and configuration management. However, for production deployments, keep the API restricted to the internal network and avoid placing it behind public endpoints.

Note: PostgreSQL supports cascading replication, allowing one standby to relay replication to others.

Step 6: Test PostgreSQL Failover

So, before putting the cluster into production, test whether Patroni properly promotes a standby when the current leader fails. This confirms that the failover process works and gives you a practical check of the cluster’s disaster recovery behavior.

First, check the current cluster state:

sudo patronictl -c /etc/patroni/patroni.yml list

Then, identify the current leader and stop Patroni on that node:

sudo systemctl stop patroni

Within a short period, Patroni should promote another node to leader. Check the cluster again:

sudo patronictl -c /etc/patroni/patroni.yml list

The failed node should appear as a replica once it returns, while another Patroni instance should show the Leader role. You should also verify that applications reach the healthy PostgreSQL node through your load balancing layer.

A successful test shows that the cluster promotes a healthy replica without requiring manual PostgreSQL intervention. For stronger testing, repeat the process with each node and verify that your applications continue to process database connections during the failure.

Note: Backup operations can be offloaded to replica nodes to reduce load on the primary server.

PostgreSQL HA Cluster Infrastructure Requirements:

To deploy a highly available PostgreSQL cluster, businesses need to carefully evaluate everything from workload demand to replication and failover systems. The environment needs to have enough GPU, RAM, storage, and network capacity for each Patroni node to have access to, especially during a failover event.

See Also: PostgreSQL vs MySQL

With that being said, before installing PostgreSQL or Patroni, there are a couple of things to verify, and some of them include the following:

  • Operating System
  • Server File System
  • PostgreSQL Versions
  • Network Connectivity
  • All Required Services

We’re going to walk you through this methodically.

Infrastructure/Server Requirements

Perhaps the most important requirement is for each Patroni node to have access to a sufficient amount of hardware resources, allowing it to replicate conditions.

  • At least 3 database servers are recommended for a resilient cluster.
  • Ensure sufficient CPU/RAM for the PostgreSQL replication or failover.
  • Use SSD or NVMe file systems with enough capacity for the database.
  • Maintain enough memory to avoid any pressure during peak workloads.
  • Place Patroni node on separate physical hosts to reduce any impact.

Note: PostgreSQL replication supports multiple synchronization modes for data consistency, making hardware availability very important.

Network and Firewall Requirements

Patroni, PostgreSQL, and etcd rely on continuous communication between the cluster components. This means that the network must offer stable connectivity while firewall rules limit access to trusted systems.

Here are some of the core networking requirements:

  • Provide reliable, low-latency connectivity between Patroni nodes.
  • Allow PostgreSQL connections required for streaming replication.
  • Guarantee full communication between Patroni and the etcd nodes.
  • Allow access to Patroni REST API from trusted hosts and systems.
  • Set up firewall rules for the cluster without exposing unnecessary ports.

A network failure between nodes affects cluster coordination, so reliable internal connectivity is essential.

Reminder: HAProxy can be configured to listen on port 5000.

PostgreSQL & Software Requirements

All nodes should run compatible PostgreSQL and supporting software versions. Consistent packages and configuration reduce unexpected behavior during replication and failover.

  • Use compatible or supported PostgreSQL versions across all nodes.
  • Install PostgreSQL, Patroni, and etcd on the required Patroni nodes.
  • Configure PostgreSQL for replication and create the replication roles.
  • Install Patroni dependencies and review the vital Patroni parameters.
  • Secure the Postgres password and replicator password on the cluster.

A single PostgreSQL installation creates a single database cluster by default. That’s why it’s important to check the Patroni documentation for any version-specific requirements before starting the deployment.

Note: PostgreSQL hot standbys can accept read-only queries for load distribution.

High Availability Server Clusters at ServerMania

ServerMania High Availability Server Clusters

ServerMania helps businesses with high-availability Server Clusters for businesses running demanding apps, databases, and other workloads across multiple nodes. Our Dedicated Server infrastructure, high-performance hardware, and flexible networking options give you the resources needed to build resilient PostgreSQL environments with Patroni, etcd, and automated failover.

PostgreSQL clusters can enhance geographic distribution to lower latency for global users. Our top-tier data centers across Canada, North America, and Europe provide the global coverage and infrastructure needed to deploy resilient database environments closer to your users.

💬If you have any questions, get in touch with our 24/7 customer service or book a free consultation to discuss your PostgreSQL project with an expert. We’re available right now!

HA PostgreSQL Cluster FAQ:

What Patroni Configuration Parameters Should I Set?

The following Patroni configuration parameters cover everything from the cluster name, etcd endpoints, PostgreSQL connection details, authentication, and REST API settings. You should review the following environment variables and confirm which default value applies before changing the system’s behavior.

How Do I Run the Patroni REST API?

You run patroni rest api by defining the REST API listener and address in the Patroni YAML configuration, then starting Patroni with the configuration file.

The API accepts rest api requests, including parallel REST API requests, and helps applications and administrators process REST API requests related to cluster status and operations.

How Much Memory Does a PostgreSQL HA Cluster Need?

PostgreSQL performance depends on the virtual memory allocated, available free memory, and overall memory usage on each node. If there is not enough memory, memory pressure can cause PostgreSQL processes to slow down or terminate, so ensure the system has enough free memory and avoid strict memory limits unless you understand their impact.

How Does Patroni Handle Data Changes?

Patroni and PostgreSQL can replicate data changes between nodes, while the primary handles requests involving SQL queries and writes. A client usually maintains a single database connection to the active PostgreSQL endpoint, while Patroni manages which node serves the entire database.

Does Patroni Support Multi-Master PostgreSQL?

Patroni does not provide multi master PostgreSQL replication because a single leader handles writes while other nodes operate as replicas. This design supports Patroni high availability by allowing Patroni to promote a replica when the primary fails without observing unexpected behavior.

What Should I Check When Patroni or PostgreSQL Behaves Unexpectedly?

First, check all the environment variables configured. Then proceed with all the operating system reports, PostgreSQL logs, and memory error kernel logs when investigating failures across the cluster, especially under strict memory conditions.

For newer deployments, check recent Patroni releases and verify that PostgreSQL processes started correctly before investigating more complex cluster problems.