Skip to content

How to Enable PostgreSQL Logical Replication

August 2026

PostgreSQL logical replication works when the server is configured for WAL logical decoding, the replication user has the right privileges, and the slot and publication boundary is deliberate.

Short Answer

To enable PostgreSQL logical replication, set wal_level = logical, make sure max_replication_slots leaves room for at least one slot, and use a replication user that has the REPLICATION attribute or superuser rights. In Skippr, the final switch is cdc_enabled: true, after which Skippr uses pgoutput, creates a replication slot and publication, and streams row-level changes in real time.

A minimal production-minded setup looks like this: wal_level = logical, max_replication_slots = 10, ALTER ROLE replicator WITH REPLICATION LOGIN;, then a source config with host, port, user, password, database, and cdc_enabled: true. If those pieces are aligned, PostgreSQL will retain WAL for the slot and Skippr can resume from the committed LSN on restart instead of starting over.

Why Teams Struggle with This

Logical replication usually fails for boring reasons rather than mysterious ones. Teams often turn on CDC in the client before the server has actually been prepared to act like a logical replication source.

  • Changing wal_level requires a PostgreSQL restart, so editing postgresql.conf without restarting leaves the server in the old mode.
  • A normal read-only database user is not enough for slot-based CDC. The replication user needs the REPLICATION attribute or equivalent superuser capability.
  • If max_replication_slots is exhausted, Skippr cannot create or reuse the slot it needs for durable resume behavior.
  • Network access and table-read permissions still matter. A replication-capable user that cannot reach the server from the runner or cannot read the selected tables is not a working CDC setup.

How Skippr Handles It

Skippr keeps the PostgreSQL CDC boundary explicit. You are not configuring an abstract sync product. You are configuring ordinary PostgreSQL connection settings plus cdc_enabled, with optional replication_slot_name and publication_name when you want named objects instead of the defaults.

That maps cleanly to operations. Skippr stores the committed LSN after each batch, reuses the replication slot across restarts, and leans on PostgreSQL to retain WAL until the changes are confirmed. If lag grows or WAL retention becomes a concern, the fix path is visible because the slot is a real PostgreSQL object with real server-side consequences.

  • Uses PostgreSQL WAL logical replication with the pgoutput plugin.
  • Enables CDC through one source-level field: cdc_enabled: true.
  • Supports explicit replication_slot_name and publication_name when teams want stable object names.
  • Resumes from the stored LSN instead of replaying from the beginning.

What the First Useful Version Looks Like

The first useful version is one PostgreSQL database, one replication user, one slot, and one or two well-understood tables such as public.orders and public.customers. That is enough to prove inserts, updates, and deletes arrive with the shape you expect before you widen discovery.

If you are enabling this on an existing production server, treat slot creation and WAL retention as part of the rollout, not as an afterthought. A working setup is not just cdc_enabled: true; it is a server that can keep up with the replication slot without silently building retention pressure.