Back to tutorials
Tutorial

Linux VPS PostgreSQL Replication Tutorial: Master-Slave Setup with Streaming Replication on Ubuntu 24.04 in 2026

Complete PostgreSQL replication tutorial for Ubuntu VPS. Set up master-slave streaming replication with automatic failover and monitoring.

By Anurag Singh
Updated on May 02, 2026
Category: Tutorial
Share article
Linux VPS PostgreSQL Replication Tutorial: Master-Slave Setup with Streaming Replication on Ubuntu 24.04 in 2026

PostgreSQL streaming replication creates real-time copies of your database across multiple servers. This gives you both high availability and read scalability. This tutorial walks through setting up master-slave PostgreSQL replication on Ubuntu 24.04 VPS instances, complete with monitoring and basic failover procedures.

You'll configure one primary server that handles all writes. You'll also set up one or more standby servers that receive continuous updates. The standby can serve read queries while staying synchronized with the master.

Prerequisites and Server Requirements

You need at least two Ubuntu 24.04 VPS instances with PostgreSQL 16 installed. Both servers should have at least 2GB RAM and reliable network connectivity between them.

Install PostgreSQL on both servers:

sudo apt update
sudo apt install postgresql-16 postgresql-contrib-16
sudo systemctl enable postgresql
sudo systemctl start postgresql

Set a password for the postgres user on both systems:

sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'your_secure_password';"

The HostMyCode VPS hosting platform provides the consistent network performance needed for reliable database replication between server instances.

Configure the Master Server

The master server handles all write operations and streams changes to standby servers.

Edit /etc/postgresql/16/main/postgresql.conf:

listen_addresses = '*'
wal_level = replica
max_wal_senders = 3
max_replication_slots = 3
wal_keep_size = 64MB
archive_mode = on
archive_command = 'test ! -f /var/lib/postgresql/16/main/archive/%f && cp %p /var/lib/postgresql/16/main/archive/%f'
log_replication_commands = on

Create the archive directory:

sudo -u postgres mkdir -p /var/lib/postgresql/16/main/archive
sudo chmod 700 /var/lib/postgresql/16/main/archive

Configure authentication in /etc/postgresql/16/main/pg_hba.conf. Add these lines for replication connections:

# Replication connections
host replication replicator 192.168.1.0/24 md5
host all all 192.168.1.0/24 md5

Replace 192.168.1.0/24 with your actual network range.

Create a dedicated replication user:

sudo -u postgres createuser --replication --pwprompt replicator

Restart PostgreSQL to apply configuration changes:

sudo systemctl restart postgresql

Set Up the Standby Server

The standby server receives streaming updates from the master.

Stop PostgreSQL first:

sudo systemctl stop postgresql

Remove the existing data directory. Then create a base backup from the master:

sudo -u postgres rm -rf /var/lib/postgresql/16/main/*
sudo -u postgres pg_basebackup -h MASTER_IP -D /var/lib/postgresql/16/main -U replicator -v -P -W

Replace MASTER_IP with your master server's IP address. Enter the replicator password when prompted.

Create a standby.signal file to mark this as a standby server:

sudo -u postgres touch /var/lib/postgresql/16/main/standby.signal

Configure the standby connection in /var/lib/postgresql/16/main/postgresql.auto.conf:

primary_conninfo = 'host=MASTER_IP port=5432 user=replicator password=replicator_password'
restore_command = 'cp /var/lib/postgresql/16/main/archive/%f %p'
archive_cleanup_command = 'pg_archivecleanup /var/lib/postgresql/16/main/archive %r'

Start PostgreSQL on the standby:

sudo systemctl start postgresql

Verify Replication Status

Check replication on the master server:

sudo -u postgres psql -c "SELECT client_addr, state, sync_state FROM pg_stat_replication;"

This should show your standby server's IP address with streaming state.

On the standby server, verify it's receiving data:

sudo -u postgres psql -c "SELECT pg_is_in_recovery();"

This should return t (true). This confirms the server is in recovery mode and receiving replication data.

Test data synchronization by creating a test database on the master:

sudo -u postgres createdb test_replication
sudo -u postgres psql -d test_replication -c "CREATE TABLE test_data (id SERIAL PRIMARY KEY, created_at TIMESTAMP DEFAULT NOW());"

Check if the database appears on the standby within seconds:

sudo -u postgres psql -l | grep test_replication

Configure Streaming Replication Security

Secure the replication connection with SSL.

Generate SSL certificates on the master server:

sudo -u postgres openssl req -new -x509 -days 365 -nodes -text -out server.crt -keyout server.key -subj "/CN=postgres-master"
sudo -u postgres chmod og-rwx server.key

Copy the certificate to the standby server. Enable SSL in postgresql.conf:

ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'

Update the standby's connection string to use SSL:

primary_conninfo = 'host=MASTER_IP port=5432 user=replicator password=replicator_password sslmode=require'

The database security hardening guide covers additional PostgreSQL security measures that complement replication setup.

Monitor Replication Lag and Performance

Track replication health with monitoring scripts.

Create /usr/local/bin/check_replication.sh:

#!/bin/bash
LAG_QUERY="SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::int;"
LAG_SECONDS=$(sudo -u postgres psql -t -c "$LAG_QUERY" | xargs)

if [ "$LAG_SECONDS" -gt 60 ]; then
    echo "WARNING: Replication lag is ${LAG_SECONDS} seconds"
    exit 1
else
    echo "OK: Replication lag is ${LAG_SECONDS} seconds"
    exit 0
fi

Make it executable and test:

sudo chmod +x /usr/local/bin/check_replication.sh
sudo /usr/local/bin/check_replication.sh

Monitor key replication metrics on the master:

sudo -u postgres psql -c "SELECT application_name, client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag FROM pg_stat_replication;"

Track WAL file generation rate:

sudo -u postgres psql -c "SELECT pg_current_wal_lsn(), pg_walfile_name(pg_current_wal_lsn());"

Handle Failover Scenarios

When the master fails, promote the standby to become the new primary:

sudo -u postgres pg_promote

This immediately promotes the standby to accept write connections. Update your application connection strings to point to the new master.

To bring the old master back online as a standby, rebuild it from the new master using pg_basebackup. Follow the same steps used to set up the original standby.

For automatic failover, consider tools like Patroni or repmgr. The PostgreSQL high availability setup guide covers these advanced clustering solutions.

Optimize Replication Performance

Tune these parameters based on your network and workload:

# In postgresql.conf on master
max_wal_size = 2GB
min_wal_size = 80MB
wal_buffers = 16MB
synchronous_commit = off
wal_writer_delay = 200ms

For high-traffic applications, consider asynchronous replication to reduce write latency. Set synchronous_standby_names = '' on the master.

Monitor network bandwidth usage between servers:

sudo iftop -i eth0 -f "host MASTER_IP or host STANDBY_IP"

The database performance tuning tutorial includes additional optimization techniques that apply to PostgreSQL replication environments.

PostgreSQL replication requires reliable network connectivity and consistent server performance between your database nodes. HostMyCode VPS hosting provides the stable infrastructure needed for production database replication with predictable network latency and high availability.

Troubleshooting Common Issues

Check PostgreSQL logs when replication stops working:

sudo tail -f /var/log/postgresql/postgresql-16-main.log

Common problems and solutions:

Replication slot conflicts: List and drop unused slots on the master:

sudo -u postgres psql -c "SELECT slot_name, active FROM pg_replication_slots;"
sudo -u postgres psql -c "SELECT pg_drop_replication_slot('slot_name');"

WAL file accumulation: Increase wal_keep_size or set up WAL archiving properly:

sudo du -sh /var/lib/postgresql/16/main/pg_wal/

Connection timeouts: Adjust wal_sender_timeout and wal_receiver_timeout in postgresql.conf.

Reset replication from scratch if corruption occurs. Stop the standby, remove its data directory, and rebuild from a fresh pg_basebackup.

FAQ

Can I run read queries on the standby server?

Yes, standby servers support read-only queries by default. This is called "hot standby" mode and helps distribute read traffic across your database cluster.

How much replication lag is normal?

Typical replication lag should stay under 1 second on local networks. Lags over 10 seconds usually indicate network issues, high master load, or configuration problems.

What happens if the network connection between servers breaks?

The standby will fall behind but continue running read queries using cached data. When connectivity returns, it automatically resumes streaming replication from where it left off.

Can I set up multiple standby servers?

Yes, PostgreSQL supports multiple standbys connected to one master. Each standby connects independently and receives the same replication stream.

Do I need shared storage for PostgreSQL replication?

No, streaming replication uses separate storage on each server. The standby maintains its own copy of the database that stays synchronized through the replication stream.

Linux VPS PostgreSQL Replication Tutorial: Master-Slave Setup with Streaming Replication on Ubuntu 24.04 in 2026 | HostMyCode