Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk12 min

How to Set Up PostgreSQL Primary–Standby (Master–Slave) Replication on Ubuntu

Set up PostgreSQL primary–standby streaming replication on Ubuntu, initialize a replica with pg_basebackup, verify WAL flow, monitor slots and lag, and plan safe promotion and recovery.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PostgreSQL physical streaming replication copies WAL (write-ahead log) records from a writable primary server to a read-only standby. On Ubuntu, the reliable sequence is to prepare two compatible hosts, configure replication on the primary, create a consistent standby with pg_basebackup, start streaming, then monitor lag and WAL retention. Streaming is asynchronous unless you explicitly configure synchronous commit behavior, so an unplanned primary failure can lose commits that had not reached the standby.

This guide uses current PostgreSQL terms. The title’s “master-slave” wording refers to the same primary-and-standby arrangement, not to a separate PostgreSQL feature.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What PostgreSQL replication does—and what it does not do

Physical streaming replication sends a primary’s WAL records to one or more standbys. The standby replays those records against a copy of the entire cluster, making it suitable for disaster recovery, read-only workloads, and a manually operated failover. It is physical replication: it copies database changes at the storage/WAL level rather than selecting individual tables.

  • The primary accepts writes.
  • A standby receives and replays WAL, normally remaining in recovery mode.
  • Replication does not automatically elect a new leader, redirect clients, fence an old primary, prevent split brain, or provide historical backups.
  • Keep independent backups and test point-in-time recovery; a promoted or damaged standby is not a substitute for them.

Prerequisites for two Ubuntu hosts

Use a primary and a standby with network reachability on PostgreSQL’s listening port (normally 5432), synchronized clocks, matching PostgreSQL major versions, and enough disk for the base copy plus retained WAL. Confirm the actual package, service unit, configuration directory, and data directory before editing anything. Ubuntu package layouts commonly resemble /etc/postgresql/<major>/main/ and /var/lib/postgresql/<major>/main/, but the installed major version determines the path.

  • Give each host a stable address or DNS name and restrict firewall access to the standby’s address.
  • Use a protected administrative path (console or SSH) so a configuration error does not lock you out.
  • Record the primary address, standby address, PostgreSQL major version, service name, data directory, and intended slot name.
  • Ensure the standby data directory can be replaced; pg_basebackup creates a complete cluster copy.

Find the installed version and units instead of assuming them:

psql --version
systemctl list-units --type=service 'postgresql*'
pg_lsclusters

Configure the primary for physical replication

Set WAL level and sender capacity

Edit the primary’s active postgresql.conf (or use an equivalent supported configuration method). Set a WAL level suitable for physical replication and reserve enough WAL sender processes:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
wal_level = replica
max_wal_senders = 10

PostgreSQL documents a default max_wal_senders value of 10. The value must be greater than the number of standbys and concurrent base-backup connections you expect. A value of zero disables replication. If you run several standbys or backups, increase it accordingly rather than copying the default blindly.

Create a dedicated replication role

Connect locally as the PostgreSQL administrative account and create a login used only for replication. Use a long, unique secret and protect it as you would any other database credential:

sudo -u postgres psql
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'replace-with-a-long-random-secret';

Do not use the general application owner for this connection. A dedicated role makes auditing, rotation, and access removal clearer.

Allow only the standby in pg_hba.conf

Add a narrow rule to the primary’s active pg_hba.conf. Replace STANDBY_IP with the standby’s address and choose an authentication method supported by your installation:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
host    replication    replicator    STANDBY_IP/32    scram-sha-256

The special replication database field applies to replication protocol connections. Do not use a broad network range when one standby address is sufficient. Also restrict the host firewall to PostgreSQL’s port and the standby address.

Reload or restart correctly

Authentication rules can normally be applied with a reload. Parameters that require startup, such as some WAL settings, require a restart. Check the parameter’s context in the installed PostgreSQL documentation and then use the package’s actual service unit:

sudo systemctl reload postgresql
sudo systemctl restart postgresql

On installations with cluster-specific units, the command may instead be expressed through the cluster wrapper, for example sudo pg_ctlcluster <major> main restart. Verify the result with systemctl status and the PostgreSQL log before proceeding.

Decide whether to use a physical replication slot

A slot records how far a standby has consumed WAL. It prevents the primary from removing WAL that the slot still requires, which lets a temporarily disconnected standby catch up without an immediate re-seed. The cost is disk risk: an abandoned or permanently broken slot can retain WAL until the pg_wal filesystem fills.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a physical slot on the primary if your operating procedure includes slot monitoring:

sudo -u postgres psql -c "SELECT pg_create_physical_replication_slot('standby1');"

If you do not use a slot, configure WAL archiving and a recovery procedure that can supply missing segments. Without either a usable archive or sufficient retained WAL, a standby that falls too far behind must be initialized again from a fresh base backup.

Choice Disconnected-standby recovery Storage risk Operational requirement
Physical replication slot Retains required WAL on the primary until the standby advances. An inactive slot can consume all available pg_wal space. Monitor slot activity, restart-LSN age, and free disk; consider max_slot_wal_keep_size as a limit.
WAL archiving Allows a lagging standby to retrieve archived segments when the archive is healthy. Archive storage and retention must be sized and maintained. Monitor archive success, retrieval, retention, and restore procedures.

Initialize the standby with pg_basebackup

pg_basebackup takes a consistent copy of the entire running cluster over the replication protocol. It is the normal starting point for a physical streaming standby.

Stop the standby and protect the target directory

On the standby, stop PostgreSQL and confirm that no process is using the target data directory. Move an old directory aside or remove it only after verifying that it contains nothing you need:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo systemctl stop postgresql
sudo mv /var/lib/postgresql/<major>/main /var/lib/postgresql/<major>/main.before-reseed
sudo install -d -o postgres -g postgres -m 700 /var/lib/postgresql/<major>/main

Use the real data directory reported by pg_lsclusters; never delete a directory based solely on an assumed version.

Run the base backup

Run this from the standby, connecting to the primary. The -R option writes standby connection settings and creates the startup marker needed by current PostgreSQL versions. The -X stream option streams required WAL during the backup:

sudo -u postgres pg_basebackup 
  -h PRIMARY_HOST -p 5432 -U replicator 
  -D /var/lib/postgresql/<major>/main 
  -Fp -P -R -X stream -S standby1

The role must pass the primary’s pg_hba.conf rule. If you did not create a slot in advance, you can have pg_basebackup create one with -C -S standby1, provided the role has the required permission. Do not combine that creation step with an already existing slot of the same name.

For unattended operation, avoid putting a reusable password in a command line or world-readable file. Use a .pgpass file owned by postgres with mode 600, or an equivalent secret manager. A matching entry contains the primary host, port, replication database field, role, and password.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check ownership and generated files

After the backup finishes, verify that the copied directory and its contents are owned by the PostgreSQL operating-system user. Confirm that the directory contains standby.signal and that postgresql.auto.conf or the chosen configuration contains the generated primary_conninfo. If you use a slot, ensure the name is exactly standby1 (or your chosen name) in the standby configuration.

Configure the standby connection and startup behavior

Set or review the following settings in the copied data directory. pg_basebackup -R usually writes the connection information, but inspect it rather than assuming it is correct:

primary_conninfo = 'host=PRIMARY_HOST port=5432 user=replicator application_name=standby1'
primary_slot_name = 'standby1'
hot_standby = on

Keep the password out of broadly readable configuration files when possible; use the protected .pgpass entry described above. hot_standby = on allows read-only queries while recovery replays WAL. Reads can be behind the primary, and recovery conflicts can cancel long-running queries, so do not treat the standby as a current, writable copy.

Start the cluster with the correct Ubuntu service command:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo systemctl start postgresql
sudo systemctl status postgresql

If your installation exposes a versioned unit, use that unit instead. The standby should remain in recovery mode; it must not start as an independent writable cluster.

Verify that streaming is active

Check the primary’s sender view

On the primary, inspect pg_stat_replication:

sudo -u postgres psql -x -c "SELECT application_name, client_addr, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn, reply_time FROM pg_stat_replication;"

Find the standby’s row and confirm state is streaming. The address, application name, and LSN columns should identify the expected host. sync_state will normally be async unless you have configured it as a synchronous candidate.

Check the standby receiver and recovery state

On the standby, run:

sudo -u postgres psql -c "SELECT pg_is_in_recovery();"
sudo -u postgres psql -x -c "SELECT status, receive_start_lsn, received_lsn, latest_end_lsn, latest_end_time, conninfo FROM pg_stat_wal_receiver;"
sudo -u postgres psql -c "SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn(), pg_last_xact_replay_timestamp();"

pg_is_in_recovery() should return true while the server is a standby. A connected receiver and advancing LSNs show that WAL is arriving and being replayed.

Perform a harmless end-to-end test

Create a temporary test table or row on the primary, wait for replay, and query it read-only on the standby. Remove the test object afterward. This catches incorrect hostnames, authentication, firewall rules, data-directory mistakes, and a standby that is receiving WAL but not replaying it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose asynchronous or synchronous replication

Streaming replication is asynchronous by default. A primary can report a commit before the standby has received or replayed its WAL. If the primary fails at that point, the standby may not contain those commits. The possible loss is not a universal number of seconds: it depends on network, storage, workload, and the exact receive position at the failure.

Axis Asynchronous Synchronous
Commit latency Primary commits without waiting for a standby acknowledgement; usually lower latency. Required acknowledgements add network and standby durability latency.
Primary failure Transactions not yet replicated can be lost after promotion. Configured synchronous acknowledgements provide a stronger durability boundary, subject to the selected policy and connected standbys.
Standby unavailable Writes continue; lag and eventual data loss exposure grow. Writes can wait or fail when the required synchronous standby is unavailable.
Read staleness Standby reads can lag the primary. Commit acknowledgement reduces acknowledged-commit exposure, but replay and query routing still need monitoring.
Operational complexity Lower; you must monitor lag and define an explicit loss boundary. Higher; configure names, quorum or priority behavior, and availability procedures.
Best fit Workloads prioritizing write availability and accepting a bounded, monitored loss window. Workloads where acknowledged commits need stronger protection and added latency is acceptable.

Configure synchronous commit deliberately

Use synchronous_standby_names on the primary to identify eligible standby names, matching the standby’s application_name. PostgreSQL considers synchronous standbys to be the names in that list that are currently connected and streaming in real time. Choose an appropriate synchronous_commit policy for the sessions or cluster. Test both normal operation and the behavior when the required standby is stopped; the durability gain is purchased with reduced write availability when the acknowledgement cannot arrive.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Monitor lag, WAL retention, and disk space

Monitoring is part of the deployment, not an optional refinement. On the primary, collect connection state, LSN positions, and slot status at an interval appropriate to your recovery objective:

sudo -u postgres psql -x -c "SELECT application_name, client_addr, state, sync_state, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn)) AS replay_bytes_behind FROM pg_stat_replication;"
sudo -u postgres psql -x -c "SELECT slot_name, slot_type, active, restart_lsn, wal_status, safe_wal_size FROM pg_replication_slots;"
df -h /var/lib/postgresql/<major>/main

Column availability can vary by major version, so adapt the query to the installed release. Alert on a disconnected receiver, increasing replay delay, failed WAL archiving, an inactive slot whose restart position continues to age, and low free space on the filesystem containing pg_wal. There is no universal safe lag threshold; set one from the amount of data loss and recovery time your workload can tolerate.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What to do when a standby falls behind

  1. Check the standby receiver log, DNS or address, firewall, credentials, and PostgreSQL service status.
  2. Check whether the primary still retains the required WAL through the configured slot or archive.
  3. Inspect slot growth and free space before restarting anything; do not allow an abandoned slot to fill the primary’s disk.
  4. If required WAL has been removed and no archive can supply it, stop the standby and seed it again with a new pg_basebackup.
  5. After recovery, verify state = 'streaming', advancing receive/replay LSNs, and a successful test row.

Troubleshoot a standby that is not streaming

No row in pg_stat_replication

  • Confirm the standby service is running and the data directory contains standby.signal.
  • Check primary_conninfo for the correct host, port, user, and application name.
  • Test network reachability to the primary’s PostgreSQL port from the standby.
  • Read the standby log for authentication failures, name-resolution errors, or connection refusal.
  • Confirm the primary’s pg_hba.conf rule matches the standby’s actual source address and was reloaded.

Authentication or permission errors

Verify that the role has LOGIN and REPLICATION, the password source is readable only by the PostgreSQL operating-system user, and the rule uses the replication database field. A changed password requires updating the protected credential on the standby.

The standby connects but WAL does not advance

Check the primary’s sender capacity, slot status, disk space, and whether the standby is replaying or blocked by recovery conflicts. Compare sent, received, flushed, and replayed LSNs rather than looking only at a connection flag. If the slot’s retained WAL is consuming the filesystem, pause and correct the retention problem before the disk reaches zero free space.

Base backup fails

Ensure the target directory is empty or moved aside, owned by postgres, and large enough for the whole cluster. Confirm the replication rule, role password, primary reachability, and available WAL sender capacity. A base backup that completes into the wrong directory will not become the active standby, so verify the cluster’s configured data path before starting the service.

Plan promotion and rejoining before an outage

Replication supplies a copy, not an automatic failover system. Write and test a runbook that names the person or automation authorized to promote, the client-routing change, the fencing method for the old primary, and the procedure for rebuilding a standby.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Manual promotion boundary

After confirming that the primary is unavailable and fencing it so it cannot accept writes, promote the chosen standby using the supported PostgreSQL method, such as:

sudo -u postgres pg_ctlcluster <major> main promote

You can also use SELECT pg_promote(); while connected locally. Verify that pg_is_in_recovery() is false, then redirect applications to the promoted server. The exact client-routing mechanism is deployment-specific; replication alone does not change connection strings or DNS.

Rebuild the old primary safely

Never allow the old primary to reappear as a writable peer while the new primary is accepting writes. Fence it, preserve any required evidence, and re-seed it as a standby from a fresh consistent base backup (or use a separately validated rejoin procedure). Recheck roles, slots, credentials, firewall rules, and monitoring after the rebuild.

Operational checklist

  • Primary and standby run compatible PostgreSQL major versions and have synchronized clocks.
  • wal_level supports physical replication and max_wal_senders covers standbys plus base backups.
  • A dedicated replication role and narrowly scoped pg_hba.conf rule are in place.
  • The standby was initialized from a consistent pg_basebackup and uses protected credentials.
  • primary_conninfo, standby.signal, and (when selected) primary_slot_name are correct.
  • The primary shows the standby as streaming; receiver and replay positions advance on the standby.
  • Your asynchronous loss boundary or synchronous availability policy is documented.
  • Slots, archives, WAL growth, lag, receiver disconnects, and disk capacity generate alerts.
  • Independent backups, point-in-time recovery, promotion, client routing, fencing, and standby rebuilds are tested.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.