How to stream database changes with Debezium CDC
Capture row-level database changes with Debezium: enable logical replication, run Kafka Connect, register a connector, and consume ordered insert, update, and delete events from Kafka.
What and why
Change data capture (CDC) turns every insert, update, and delete in a database into an event stream. Debezium reads the database's transaction log and publishes ordered change events to Kafka, enabling cache updates, search indexing, replication, and analytics without polling. This tutorial captures changes from PostgreSQL.
Prerequisites
- A PostgreSQL instance you can reconfigure and restart.
- A Kafka cluster and a Kafka Connect runtime with the Debezium PostgreSQL connector installed.
curland a Kafka consumer for testing.
Steps
1. Enable logical replication
In postgresql.conf:
wal_level = logical
max_replication_slots = 4
max_wal_senders = 4
Restart PostgreSQL and grant the connector user REPLICATION privileges.
2. Run Kafka Connect with Debezium
Use the Debezium Connect image so the plugin is present:
docker run -d --name connect -p 8083:8083 \
-e BOOTSTRAP_SERVERS=kafka:9092 \
-e GROUP_ID=cdc -e CONFIG_STORAGE_TOPIC=connect_configs \
-e OFFSET_STORAGE_TOPIC=connect_offsets \
-e STATUS_STORAGE_TOPIC=connect_status \
debezium/connect:2.6
3. Register the connector
POST a connector config to the Connect REST API:
curl -X POST localhost:8083/connectors -H 'Content-Type: application/json' -d '{
"name": "pg-cdc",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"database.hostname": "postgres", "database.port": "5432",
"database.user": "debezium", "database.password": "secret",
"database.dbname": "app", "topic.prefix": "app",
"table.include.list": "public.orders",
"plugin.name": "pgoutput"
}
}'
4. Inspect change topics
Debezium creates a topic per table, here app.public.orders. List topics to confirm it exists.
5. Read a change event
Consume the topic and update a row; each event has a before, after, and op field (c, u, d):
kafka-console-consumer --bootstrap-server kafka:9092 \
--topic app.public.orders --from-beginning
6. Handle snapshots and offsets
On first start, Debezium snapshots existing rows, then streams new changes from the WAL. Connect stores offsets so restarts resume without loss. Monitor the replication slot so it does not retain WAL indefinitely if the connector stops.
Verification
Insert, update, and delete a row in orders; you should see matching c, u, and d events in the topic in commit order. curl localhost:8083/connectors/pg-cdc/status should report RUNNING.
Next Steps
Add a sink connector to land changes in a warehouse, use the outbox pattern for reliable event publishing, and configure schema history and SMTs to shape events.
Prerequisites
- A PostgreSQL database
- A running Kafka cluster
- Kafka Connect available
Steps
- 1Enable logical replication
- 2Run Kafka Connect with Debezium
- 3Register the connector
- 4Inspect change topics
- 5Read a change event
- 6Handle snapshots and offsets