Managed Postgres CDC
August 12, 2026 ยท View on GitHub
KafkaConnector runs one operator-managed PostgreSQL logical-decoding worker
and writes its change records to Crabka topics. The initial implementation
supports PostgreSQL sources only.
Prerequisites
- Install the Crabka operator and the
KafkaConnectorCRD. - Run a Confluent-compatible Schema Registry reachable at
spec.schemaRegistryUrl. The worker registers its CDC key and value schemas there before connecting to PostgreSQL. - In the connector namespace, provide a ready
Kafkanamed by thecrabka.io/clusterlabel. It must expose an internal TLS listener with TLS client authentication; the operator creates the connector'sKafkaUserand mounts its credentials. - Configure PostgreSQL with logical decoding (
wal_level=logical). The URL Secret must identify a user allowed to read the selected tables and manage or use the publication and logical replication slot. - Give captured tables stable keys. Set an appropriate PostgreSQL replica identity when update or delete events must include enough key data.
The connector creates the configured publication and pgoutput logical slot
when they are absent, so its PostgreSQL user needs those privileges. If they
already exist, the publication must cover every configured table, publish
insert/update/delete but not truncate, and the slot must be a logical
pgoutput slot for the same database. Table names in the example are relative
to spec.schema.
Apply and observe
Copy the example manifest, replace the namespace, cluster name, and database URL, then apply it:
kubectl apply -f docs/examples/kafka-connector-postgres.yaml
kubectl -n streaming get kafkaconnector orders-cdc -w
The operator reports Ready, Paused, and Failed conditions and creates a
Deployment with the same name as the connector. Inspect progress with:
kubectl -n streaming describe kafkaconnector orders-cdc
kubectl -n streaming get deployment orders-cdc
kubectl -n streaming logs deployment/orders-cdc
Invalid configuration and missing Secrets appear in status instead of starting a worker. The database Secret must be in the connector's namespace.
Pause and resume
Pausing retains the durable checkpoint and scales the worker to zero:
kubectl -n streaming patch kafkaconnector orders-cdc --type=merge \
-p '{"spec":{"paused":true}}'
Set paused back to false to create one worker replica and resume from the
saved LSN:
kubectl -n streaming patch kafkaconnector orders-cdc --type=merge \
-p '{"spec":{"paused":false}}'
Topics and delivery
The source names each record after its schema-qualified relation. The worker
prepends spec.topicPrefix with a dot; the default prefix is db. For example,
public.orders is written to db.public.orders. Kafka chooses the partition
from the encoded row key. Deletes are keyed tombstones, and records retain the
PostgreSQL table, operation, and LSN headers.
Delivery is at least once. The worker first obtains Kafka acknowledgement for
the data, then durably stores the LSN in the compacted
__crabka_connect_offsets topic, and only then advances the PostgreSQL slot. A
crash after the data acknowledgement but before the checkpoint is durable can
replay records after restart. Consumers must tolerate duplicates; keys and the
crabka.pg.lsn header can support idempotent processing. This contract avoids
advancing the source beyond durably acknowledged Kafka data, but it is not
exactly-once source delivery.
Checkpoint keys include a hash of the PostgreSQL URL and slot, so repointing a connector does not load an incompatible offset from its former source. Topics created by the worker use up to three replicas, bounded by the managed cluster's broker count.
Health and metrics
The worker listens on port 8080 inside its pod:
/livereturns success while the worker process is live./readyreturns success while the connector runtime can process records./metricsexposes OpenMetrics counters and live/ready gauges.
Kubernetes uses /live and /ready for its probes. For direct inspection:
kubectl -n streaming port-forward deployment/orders-cdc 8080:8080
curl http://127.0.0.1:8080/metrics
Current scope
This release does not provide initial database snapshots, exactly-once source delivery, arbitrary source or sink plugins, JVM connector loading, the Kafka Connect distributed-worker protocol or REST API, multiple tasks per connector, or more than one worker replica per connector.