PostgreSQL Setup
CDC Watcher uses PostgreSQL logical replication (WAL). No triggers, no extensions — just configure wal_level.
Requirements
-- postgresql.conf
wal_level = logical
max_replication_slots = 5
max_wal_senders = 5
-- Restart PostgreSQL after changing these
The provided docker-compose.yml already has this pre-configured.
Verify
SHOW wal_level;
-- Should return: logical
Auto-created resources
On first run, the library automatically creates:
- A replication slot (
cdc_slotby default) - A publication (
cdc_publication FOR ALL TABLES)
Configurable:
app.cdc.postgres.slot-name=my_slot
app.cdc.postgres.publication-name=my_publication
app.cdc.postgres.create-slot-if-not-exists=true
app.cdc.postgres.create-publication-if-not-exists=true
REPLICA IDENTITY
Controls how much data appears in UPDATE/DELETE events:
| Setting | INSERT | UPDATE | DELETE |
|---|---|---|---|
DEFAULT | full row | new values only | primary key only |
FULL | full row | old + new values | full deleted row |
-- Required for full before/after data in UPDATE and DELETE
ALTER TABLE orders REPLICA IDENTITY FULL;
Recommendation: use REPLICA IDENTITY FULL for any table where consumers need the complete row on DELETE or need to diff old vs new on UPDATE.
Column Names
PostgreSQL WAL uses the RELATION message from the pgoutput protocol to resolve real column names. Excalibase Watcher reads these automatically — no manual mapping required. Events include actual column names (id, product, qty) for both INSERT, UPDATE, and DELETE.
DDL Capture
Capture schema changes (CREATE TABLE, ALTER TABLE, DROP TABLE) as CDC events:
app.cdc.postgres.capture-ddl=true
DDL events are published to cdc.{schema}.{table} with type: "DDL" and the DDL statement in the data field.
Snapshot Mode
On first startup, you may want to capture all existing rows before streaming live changes:
# Options: none (default), initial, schema_only
app.cdc.postgres.snapshot-mode=initial
| Mode | Behavior |
|---|---|
none | Only capture changes from now on |
initial | Snapshot all existing rows on first start, then stream changes |
schema_only | Capture schema structure only, then stream changes |
Table Filtering
Watch specific tables instead of all:
# Comma-separated list (empty = all tables)
app.cdc.postgres.tables=orders,products,customers
This creates a publication for only the specified tables.
Full Application Config
# Database connection
app.cdc.postgres.url=jdbc:postgresql://localhost:5432/mydb
app.cdc.postgres.username=postgres
app.cdc.postgres.password=postgres
# CDC settings
app.cdc.postgres.enabled=true
app.cdc.postgres.slot-name=cdc_slot
app.cdc.postgres.publication-name=cdc_publication
app.cdc.postgres.capture-ddl=true
app.cdc.postgres.snapshot-mode=none
app.cdc.postgres.tables=
# NATS
app.cdc.nats.url=nats://localhost:4222
app.cdc.nats.stream-name=cdc-stream