Common symptoms
- The replica is several gigabytes or minutes behind the primary according to monitoring
- pg_stat_replication shows write_lag, flush_lag or replay_lag different from zero and growing
- pg_replication_slots shows slots with wal_status = 'lost' or negative safe_wal_size
- The replica serves stale data to read-only applications
- Monitoring system alerts about replication delay exceeding the threshold
- The primary server's disk fills up due to WAL retention (inactive slot)
Business risks
- If the primary fails with the replica delayed, the difference in data is lost (exceeds the RPO)
- An inactive replication slot can fill the primary's disk and cause a total outage
- Reporting and BI applications reading from the replica receive inconsistent data
- The DR replica cannot be used as a reliable failover if it has minutes of lag
Detailed technical checklist
- 1. Confirm the WAL sender process is active on the primary If pg_stat_replication doesn't show the replica or it appears with state = 'startup', the replication process is not established.
- 2. Confirm walreceiver is running on the replica If the process doesn't appear, the replica has stopped connecting to the primary.
- 3. Detect inactive slots accumulating WAL A slot with active = false retains WAL indefinitely. If safe_wal_size is negative, the disk is already at risk.
- 4. Drop an inactive slot that is no longer needed Only if you are certain the subscriber will not return. This action is irreversible.
- 5. Verify network connectivity and latency between nodes If latency between primary and replica exceeds 10–50ms, lag can accumulate under high load.
- 6. Review pg_hba.conf for replication permissions There must be a line with the correct authentication method for the replication user.
- 7. Verify replication limits in postgresql.conf If there are more replicas than max_wal_senders, new ones won't be able to connect.
- 8. For logical replication: review subscription status srsubstate = 'r' indicates the worker is running. 'd' means it is initializing data.
- 9. Check if an intentional apply delay is configured recovery_min_apply_delay introduces a deliberate delay in the replica. Verify it is set to 0 if you don't need it.
- 10. Measure if the replica can catch up to the primary on its own Monitor the lag every 30 seconds for 5 minutes. If it decreases, the replica can catch up on its own. If it grows, there is a capacity problem.
-- Lag of each replica, in bytes
SELECT client_addr, state,
pg_wal_lsn_diff(sent_lsn, replay_lsn) AS lag_bytes
FROM pg_stat_replication;
When to escalate to a specialist DBA
- The replication slot has wal_status = 'lost' — the WAL is no longer available and the replica must be rebuilt from scratch
- The primary's disk is full or above 90% due to WAL retention from an inactive slot
- The DR replica has more lag than the RPO approved by the business
- There is no way to synchronize without a new pg_basebackup (full base from the primary)
- A planned failover is approaching and the replica is not in condition to take over
Frequently asked questions
Why does replication lag increase during the day and drop at night?
Generally indicates that the write load on the primary during peak hours exceeds the capacity of the network or the apply process on the replica. The replica cannot apply changes as fast as they arrive. Review max_wal_size, network latency between nodes and whether the replica server has sufficient I/O for the apply process.
Can an inactive replication slot fill the primary's disk?
Yes, and it is one of the most serious risks of PostgreSQL in production. An inactive logical or physical slot retains all WAL generated since the last confirmed point. If the replica or subscriber disappears without the slot being dropped, WAL accumulates until it fills the primary's disk, which can cause a total server outage. Monitoring safe_wal_size in pg_replication_slots must be part of daily monitoring.
Does logical replication replicate DDL (ALTER TABLE, CREATE INDEX)?
No. PostgreSQL logical replication replicates DML (INSERT, UPDATE, DELETE, TRUNCATE from v10) but not DDL. Schema changes must be applied manually on the subscriber before the corresponding DML arrives. If you apply an ALTER TABLE on the primary without doing it first on the subscriber, replication will break with an error. This is the critical difference from physical (streaming) replication, which replicates everything at the block level.
Can I use the replica for reads while it has lag?
Yes, the replica remains readable while it has lag. The problem is that reads will return stale data by the amount of the delay. If your application cannot tolerate reading data that is minutes old, you need to measure the lag and decide whether to redirect reads to the primary or temporarily block them. There is no native mechanism in the PostgreSQL protocol for "don't read if lag > N"; it must be implemented in the pooler (PgBouncer) or in the application layer.