Choosing Publication and Subscription Boundaries
For large or high-churn production tables, use one publication and one subscription per large table, or group only small related tables together. This gives each subscription its own apply worker and replication slot. In normal steady-state replication, Postgres does not parallelize ordinary change application across tables within a single subscription, so one hot table can delay other tables that share that apply worker. A publication per table alone does not provide that isolation unless it also has its own subscription. If you split replication this way, allow enough slots and workers for all your subscriptions, including extra capacity during the initial copy. On the publisher:max_replication_slots: Allow one slot per subscription, plus extra slots for table synchronization during bootstrap. With the default settings, each bootstrapping subscription can use up to two extra slots.max_wal_senders: Allow enough senders for those replication slots, plus any physical replicas.
max_replication_slotsandmax_logical_replication_workers: Allow capacity for every subscription, plus extra capacity for table synchronization.max_worker_processes: Allow enough processes for the logical replication workers and any other background workers.- On Postgres 18+, also size
max_active_replication_originsfor replication origin tracking.
Handling Tables Without Primary Keys
Postgres needs a replica identity to replicateUPDATE and DELETE
operations. A primary key is best. Another suitable unique index can also be
used as the replica identity. If a table has no suitable key, you can use the
per-table fallback:
REPLICA IDENTITY FULL is set
per published table and should be treated as a fallback rather than the default
design.
Postgres explicitly warns that subscriber-side UPDATE and DELETE can
become very inefficient under FULL, because the subscriber must locate the
matching row using the entire old row image rather than a compact key.
FULL also increases WAL volume and replication traffic on the publisher,
since every UPDATE and DELETE writes the full before-image of the row
into WAL instead of just the key columns.