Replication Slots
Replication slots tell the primary to retain WAL until a consumer confirms receipt. They prevent standbys and logical subscribers from falling off the WAL timeline.
Search across all documentation pages
Replication slots tell the primary to retain WAL until a consumer confirms receipt. They prevent standbys and logical subscribers from falling off the WAL timeline.
Create a physical slot for each standby; drop orphans promptly.
-- Physical slot for a streaming standby
SELECT pg_create_physical_replication_slot('standby1_slot');
-- Inspect lag and retained WAL
SELECT slot_name, slot_type, active, restart_lsn,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained
FROM pg_replication_slots;# Drop an unused slot (after confirming standby is decommissioned)
psql -h primary.db.internal -U postgres -c \
"SELECT pg_drop_replication_slot('old_standby_slot');"When to reach for this: Any long-lived standby, logical subscriber, or backup tool that must not lose WAL.
Create slot during base backup, monitor inactive slots:
# pg_basebackup with slot creation
pg_basebackup -h primary.db.internal -U replicator \
-D /var/lib/postgresql/18/main -Fp -Xs -P -R \
-C -S standby1_slot-- Alert query: inactive slot retaining WAL
SELECT slot_name, active,
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) AS bytes_retained
FROM pg_replication_slots
WHERE NOT active
AND pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) > 1073741824; -- 1 GiBWhat this demonstrates:
active = false with large bytes_retained signals a dead consumer filling disk.pg_basebackup -C -S pairs initial clone with slot creation in one step.| Type | Created by | Consumer |
|---|---|---|
| Physical | pg_create_physical_replication_slot, pg_basebackup -C | Streaming standby, pg_receivewal |
| Logical | pg_create_logical_replication_slot | Logical replication subscriber, CDC tools |
| Column | Meaning |
|---|---|
restart_lsn | Earliest WAL still needed by slot |
confirmed_flush_lsn | Logical subscriber acknowledged position |
active | Consumer currently connected |
wal_status | reserved, extended, unreserved, lost (PostgreSQL 18) |
Slots override wal_keep_size and can prevent WAL recycling. Combine:
max_slot_wal_keep_size as a safety valve (PostgreSQL 13+)active = false.max_slot_wal_keep_size - One bad slot can exhaust disk. Fix: Set a bounded retention policy and page on wal_status = 'lost'.| Alternative | Use When | Don't Use When |
|---|---|---|
wal_keep_size only | Ephemeral test standbys | Production standbys that may disconnect |
| Archive + restore | DR without continuous streaming | You need hot standby failover |
| Temporary slot during catch-up | One-time reseed | Long-term retention without monitoring |
Yes for production physical standbys. Logical subscribers need their own logical slots.
Physical standbys do not create sender slots; slots live on the primary (or upstream logical publisher).
The slot required WAL that was already removed. Recreate consumer from a fresh base backup.
Patroni 3.x can create and synchronize permanent replication slots across the cluster. Verify slots section in Patroni YAML.
max_slot_wal_keep_size caps retention but may invalidate lagging consumers. Prefer alerting and operational slot hygiene.
Stack versions: This page was written for PostgreSQL 18.4 (stable 18, maintenance 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, and PostGIS 3.5+.
Reviewed by Chris St. John·Last updated Jul 18, 2026