Education
14 min read

What is CDC streaming? Change data capture guide

What is CDC streaming? Learn how it reads database logs, where Kafka fits, how it differs from batch CDC, and when its operational cost is worth it.

Arsalan Noorafkan

Developer Advocate

Quick answer: CDC streaming is change data capture delivered as a stream. Instead of waiting for a nightly job to copy changed rows, a CDC reader watches the source database log and emits inserts, updates, and deletes as they happen, or close enough that downstream systems behave like they are live.

The simple version:

database transaction log -> CDC reader -> stream or topic -> consumers and destinations

CDC streaming is what you reach for when "sync the table every hour" stops being good enough.

Sometimes that is because product analytics needs fresh events. Sometimes it is because a warehouse table is too large for repeated incremental queries. Sometimes it is because multiple systems need to react to the same customer, order, payment, or inventory change. And sometimes it is because a team has already learned the hard way that polling updated_at misses deletes.

For the broader capture method, start with what is change data capture. This guide focuses on the continuous, low-latency delivery model.

The names change between PostgreSQL, MySQL, SQL Server, Oracle, Kafka, Kinesis, Pub/Sub, Debezium, Fivetran, Airbyte, Estuary, and Bruin, but the design questions stay pretty consistent: what changes are captured, how are they ordered, where do they go, how do you replay them, and what happens when the pipeline falls behind?

What CDC streaming means

CDC stands for change data capture. It means detecting changes in a source system and making them available somewhere else.

CDC streaming is the streaming version of that idea.

A database table changes:

  • a row is inserted
  • a row is updated
  • a row is deleted
  • a transaction commits
  • the database writes the change to its log

Then a CDC process reads those committed changes and sends them downstream as events.

A CDC streaming event usually contains:

  • the source table
  • the operation type, such as insert, update, or delete
  • the primary key
  • the new row values
  • sometimes the old row values
  • the source transaction position
  • the event timestamp or commit timestamp
  • metadata about the database, schema, and connector

A simplified CDC event might look like this:

{
  "source": {
    "database": "app",
    "schema": "public",
    "table": "orders",
    "position": "16/B374D848"
  },
  "operation": "update",
  "key": {
    "order_id": 1042
  },
  "before": {
    "status": "pending"
  },
  "after": {
    "status": "paid"
  },
  "committed_at": "2026-07-13T09:42:12Z"
}

That position is not decoration. It is how the CDC system knows where it is in the source log. Without a durable offset, restart behaviour becomes guesswork.

Why CDC streaming exists

Most data pipelines start as batch jobs because batch jobs are easy to reason about. Run every hour. Pull changed rows. Merge into the destination. Done.

That works for a lot of tables.

It starts to break when the table is large, mutable, and operationally important.

The classic polling pattern is:

select *
from orders
where updated_at > :last_run_time

It is simple, but it has weak spots:

  • hard deletes are invisible
  • timestamp bugs create missing rows
  • backfills can fall outside the cursor window
  • bulk updates can overload the next run
  • clock drift can create weird edge cases
  • every run still queries the source table

CDC streaming moves the capture point closer to the database itself. The database already records changes in a log so it can commit transactions, recover after failures, and replicate state. CDC uses that log as the source of truth.

The result is usually lower latency and a cleaner change history.

That does not mean CDC streaming is free. It adds more moving parts. But when freshness and correctness matter, those moving parts can be worth it.

How CDC streaming works

Every implementation has its own details, but the shape is usually the same.

1. The source database commits a transaction

An application changes data. The database commits the transaction and records the change in an internal log.

Common examples:

  • PostgreSQL writes to the write-ahead log and can expose logical changes through logical replication.
  • MySQL writes row-level changes to the binary log when configured for row-based replication.
  • SQL Server can capture committed changes from the transaction log into CDC change tables.
  • Oracle has redo logs and mature replication tooling around them.

The important part: the database log is ordered, durable, and tied to committed transactions.

2. A CDC reader consumes the log

The CDC reader connects to the source as a replication consumer or equivalent. It reads changes in order and translates database-specific log records into a more useful change event.

This reader might be an open-source connector, a managed ELT connector, a cloud migration service, or an ingestion tool embedded inside a broader pipeline platform.

3. The reader stores its offset

The reader must remember the last source position it processed safely.

Depending on the source, that offset might be:

  • PostgreSQL log sequence number
  • MySQL binlog file and position
  • SQL Server log sequence number
  • Oracle system change number
  • Kafka topic, partition, and offset
  • a connector-specific checkpoint

Offset handling is where a lot of reliability lives. A CDC streaming job should be able to stop, restart, and continue from the last safe point without silently skipping committed changes.

4. Changes are written to a stream or destination

The next hop depends on the architecture.

Common patterns:

  • publish change events to Kafka topics
  • write micro-batches into a warehouse
  • land raw events in object storage
  • update a current-state destination table
  • feed a search index or cache
  • trigger application workflows

CDC streaming does not always mean Kafka. Kafka is common because it is good at buffering, retaining, partitioning, and replaying streams, but the CDC concept is broader than one platform.

5. Consumers apply or react to changes

Downstream consumers do different jobs:

  • merge the latest row state into a warehouse table
  • build an append-only audit table
  • update materialized views
  • hydrate a feature store
  • maintain search indexes
  • trigger operational workflows
  • feed fraud, pricing, or inventory systems

This is why CDC streaming is not just "replication." Replication usually aims to keep another copy close to the source. CDC streaming often creates a reusable stream of business changes that multiple consumers can interpret differently.

CDC streaming vs batch CDC

Both models capture changes. The difference is delivery.

AreaBatch CDCCDC streaming
RuntimeRuns on a scheduleLong-running or near-continuous
LatencyMinutes to hoursSeconds to minutes
Failure modeRetry the next batchResume from a durable offset
Destination writesLarger batchesSmall batches or continuous writes
Operational concernJob duration, batch windowslag, backpressure, offset health
Best fitAnalytics syncs that can waitlive analytics, event-driven systems, operational replicas

Batch CDC is still useful. If a finance table updates a few times per day, a scheduled CDC job may be enough. Streaming CDC is useful when delay matters or when multiple consumers need a live change feed.

The mistake is treating "real time" as automatically better. Real time costs you something: infrastructure, monitoring, schema contracts, backpressure handling, and on-call expectations.

Where CDC streaming fits

CDC streaming usually sits between operational systems and analytical or event-driven systems.

Typical sources:

  • PostgreSQL
  • MySQL and MariaDB
  • SQL Server
  • Oracle
  • MongoDB
  • managed database services
  • application databases behind SaaS-like internal products

Typical destinations:

  • Kafka topics
  • cloud streams like Kinesis or Pub/Sub
  • warehouses like BigQuery, Snowflake, Redshift, Databricks, or Postgres
  • object storage in Parquet, JSON, or Avro
  • search systems
  • caches and serving databases
  • downstream application services

Typical use cases:

  • database-to-warehouse sync
  • live customer 360 tables
  • order and payment status propagation
  • inventory availability updates
  • audit trails for mutable tables
  • near-real-time dashboards
  • event-driven application integration
  • machine learning feature updates
  • migration from one database to another with minimal downtime

In a modern data stack, CDC streaming is often the ingestion layer. It does not replace transformation, quality checks, lineage, access control, semantic models, or dashboards. It makes fresher raw changes available so the rest of the stack has better inputs.

When to use CDC streaming

Use CDC streaming when at least one of these is true:

  • downstream systems need changes within seconds or minutes
  • a table is too large to scan frequently
  • updates and deletes matter
  • several consumers need the same source changes
  • you need replayable history of database mutations
  • the source database should avoid repeated heavy polling queries
  • an operational migration needs source and destination to stay close
  • you want event-driven systems without changing application code

Good examples:

  • orders moving through created, paid, fulfilled, and refunded
  • subscriptions changing status throughout the day
  • inventory rows that update after purchases and returns
  • support tickets that merge, reassign, and close
  • payments where retries, reversals, and corrections matter
  • user profile changes that feed analytics, search, and product experiences

CDC streaming is especially useful when one source change has several downstream meanings. An order update might refresh a warehouse table, trigger a fulfilment workflow, update a fraud model, and appear in a customer support tool. A stream lets those consumers move independently.

When not to use CDC streaming

Do not use CDC streaming just because it sounds more modern.

It may be the wrong default when:

  • the table is small and full refresh is cheap
  • downstream consumers only update daily
  • the source does not expose a reliable log or replication interface
  • primary keys are missing or unstable
  • deletes do not matter
  • the team has no monitoring path for lag and failed consumers
  • schema changes happen constantly and nobody owns the contract
  • the destination cannot apply changes idempotently

Sometimes the boring answer is correct. A daily snapshot for a tiny reference table is fine. An append-only event export may be simpler than CDC. A timestamp cursor may be enough if deletes are soft-deleted and updates are rare.

CDC streaming earns its keep when it solves a real latency, correctness, scale, or fan-out problem.

The main architecture decisions

Source log configuration

CDC streaming starts at the source database, so source setup matters.

For PostgreSQL, this usually means logical replication, a publication, and a replication slot. For MySQL, it usually means binary logging with row format and enough retention. Other databases have their own equivalent settings.

Two practical questions matter early:

  • Can the CDC reader see every table and column it needs?
  • Will the source retain logs long enough if the reader falls behind?

If log retention is too short, a broken consumer can fall behind past the point of recovery. At that point you may need a new snapshot.

Initial snapshot

CDC streams capture changes from a point in time. Most pipelines also need the current contents of the table before streaming begins.

That bootstrap is the initial snapshot.

A good setup defines:

  • how the initial snapshot is taken
  • whether writes continue during the snapshot
  • how the stream catches up after the snapshot
  • what happens if the snapshot fails halfway
  • whether the snapshot can be repeated safely

The handoff between snapshot and stream is one of the most important correctness points in the whole design.

Event keys and ordering

Most CDC events should be keyed by the source primary key. That lets downstream systems merge changes into the correct row and lets streaming platforms partition related events together.

Ordering is more subtle.

You usually need ordering per row or per primary key. Global ordering across every table is expensive and often unnecessary. For Kafka, key choice affects partitioning, and partitioning affects ordering. If all events for order_id = 1042 go to the same partition, consumers can process that order's changes in sequence.

Deletes and tombstones

Deletes are one of the reasons teams adopt CDC in the first place.

Decide how deletes are represented:

  • as a change event with operation = delete
  • as a tombstone message
  • as a soft-delete flag in a current-state table
  • as a row in an audit table

The destination behaviour should be explicit. Some analytics tables should remove deleted rows. Some should preserve a delete event for audit. Some should keep the last known row and mark it inactive.

Schema evolution

Source schemas change. Columns are added, renamed, widened, narrowed, or removed.

CDC streaming makes schema changes more visible because the stream is always moving. If the destination schema or consumer code cannot handle a new event shape, the pipeline can fail quickly.

Plan for:

  • compatible changes, such as adding nullable columns
  • incompatible changes, such as changing a column type
  • schema registry or contract checks if using Kafka heavily
  • versioned consumers
  • dead-letter handling for malformed records
  • alerts when schema changes break a destination merge

Delivery semantics and idempotency

People love saying "exactly once." In practice, the safer design habit is this: assume retries happen, and make the destination idempotent.

That usually means:

  • each event has a stable source position
  • current-state tables merge on primary key
  • audit tables can deduplicate by source transaction and row key
  • consumers commit offsets only after durable writes
  • replaying a range of events does not corrupt the destination

CDC streaming can be very reliable, but only if replay is boring.

Backpressure and lag

CDC streaming systems fail slowly before they fail loudly. Lag grows, queues fill, log retention shrinks, and the source slot starts retaining too much history.

Watch:

  • source log retention
  • replication slot lag
  • connector lag
  • Kafka consumer lag
  • destination write latency
  • failed merge count
  • dead-letter count
  • event throughput
  • restart frequency

Lag is not automatically bad. A short spike during a bulk update is normal. Persistent lag means the destination or consumer cannot keep up.

Security and governance

CDC readers often need elevated source permissions. They may see columns that normal application users do not query directly.

Treat CDC streams as production data:

  • use least-privilege replication users where possible
  • avoid streaming unnecessary sensitive columns
  • encrypt traffic between source, stream, and destination
  • track who owns the pipeline
  • document downstream consumers
  • apply access controls to raw topics and raw tables
  • keep lineage from source table to destination models

This is where CDC streaming crosses from "connector setup" into data platform design.

CDC streaming with Kafka

Kafka is common in CDC streaming because it gives you a durable middle layer.

With Kafka, a source table often maps to one or more topics. CDC events are written to those topics. Consumers read independently using consumer groups. Kafka keeps offsets, stores events for a retention period, and lets consumers replay from earlier positions if needed.

Kafka helps when:

  • several downstream systems need the same changes
  • consumers need replay
  • the source and destination should be decoupled
  • destination downtime should not immediately stop capture
  • event ordering by key matters
  • teams already operate Kafka well

Kafka also adds work:

  • topic naming
  • partition strategy
  • retention settings
  • compaction settings
  • schema registry
  • consumer lag monitoring
  • access control
  • dead-letter topics
  • capacity planning

So the rule is simple: Kafka is useful when you need a streaming backbone, not when you only need one database table copied into one warehouse every hour.

A practical example: orders from Postgres

Imagine a Postgres orders table.

The application writes orders all day:

  • customer creates order
  • payment succeeds
  • warehouse starts fulfilment
  • refund is issued
  • customer support cancels an item

A polling job might run every 15 minutes and query rows where updated_at changed. That can work, but it leaves gaps: hard deletes, timestamp bugs, and a constant delay.

A CDC streaming setup does this instead:

  1. Configure Postgres logical replication for public.orders.
  2. Take an initial snapshot of the table.
  3. Start reading committed changes from the replication stream.
  4. Publish each insert, update, and delete as an event.
  5. Use the order primary key as the event key.
  6. Merge changes into the warehouse orders_current table.
  7. Keep raw CDC events in an audit table or topic for replay.
  8. Monitor replication lag and destination merge failures.

Now the warehouse can stay close to the operational database without rescanning the whole table. And if someone asks why an order changed status three times in ten minutes, the raw CDC events can explain it.

CDC streaming checklist

Before you call a CDC streaming pipeline production-ready, answer these questions:

  1. Which exact tables are captured?
  2. Does every captured table have a stable primary key?
  3. How is the initial snapshot taken?
  4. Where is the source offset stored?
  5. How long does the source retain logs?
  6. What happens if the consumer is down for two hours?
  7. Are deletes preserved, merged, or ignored?
  8. How are schema changes detected?
  9. Can the destination apply events idempotently?
  10. What metrics define lag?
  11. Who gets alerted when lag grows?
  12. Can you replay a table from raw events?
  13. Which columns are sensitive?
  14. Who owns the downstream tables and consumers?
  15. What is the fallback if the stream needs to be rebuilt?

If those answers are vague, the implementation is not ready yet. The connector may run, but the pipeline is not operationally understood.

Bruin support for CDC streaming and Kafka

Bruin supports CDC streaming through ingestr assets. For PostgreSQL, the Bruin PostgreSQL CDC stream mode docs show CDC enabled with cdc: "true" and cdc_mode: stream, using PostgreSQL logical replication with the usual publication and replication slot setup.

Example:

name: public.orders
type: ingestr
connection: bigquery

parameters:
  source_connection: my_pg
  source_table: public.orders
  destination: bigquery
  cdc: "true"
  cdc_mode: stream

Bruin also supports Kafka as a source for ingestr assets. The Bruin Kafka ingestion docs describe a Kafka connection with bootstrap_servers and group_id, then an asset that reads a topic like kafka.my_topic into a destination.

That means Bruin can cover both sides of the common CDC streaming picture: database CDC through ingestr, and Kafka topic ingestion when Kafka is already part of the streaming architecture. The important bit is that the stream can live in the same reviewed pipeline graph as transformations, checks, lineage, and governance, instead of being a disconnected sync job nobody remembers until it falls behind.

FAQ

What is CDC streaming?

CDC streaming is the continuous movement of database changes from a source system into downstream systems. It captures inserts, updates, and deletes from a database log or equivalent change feed and emits them as events.

Is CDC streaming the same as CDC?

CDC is the broader method of capturing source changes. CDC streaming is the low-latency version where changes are delivered as an ongoing stream instead of only being collected during scheduled batch jobs.

Is CDC streaming real time?

Usually CDC streaming is near real time, not instantaneous. Latency depends on source log availability, connector speed, buffering, network, streaming platform, and destination writes. For most data systems, seconds or low minutes are close enough to real time.

Does CDC streaming require Kafka?

No. Kafka is common because it is good at durable streams, replay, partitions, and consumer groups. But a CDC streaming pipeline can also write directly to a warehouse, object storage, a queue, or another streaming service.

What is the difference between CDC streaming and ETL?

ETL is the broader process of extracting, transforming, and loading data. CDC streaming is one way to extract and deliver database changes. Teams still need transformations, quality checks, access controls, documentation, and downstream modelling after the stream exists.

Is CDC streaming better than batch ingestion?

It depends. CDC streaming is useful when freshness, deletes, updates, replay, or fan-out matter. Batch ingestion is often simpler for small tables, low-change tables, or workflows where hourly or daily freshness is enough.

What are common CDC streaming tools?

Common tools and platforms include Debezium, Kafka Connect, Estuary Flow, Fivetran, Airbyte, AWS DMS, Google Datastream, Oracle GoldenGate, Qlik Replicate, Kinesis, Pub/Sub, and Bruin with ingestr.

Does Bruin support CDC streaming?

Yes. Bruin supports PostgreSQL CDC stream mode through ingestr assets using cdc: "true" and cdc_mode: stream. Bruin also supports Kafka ingestion through ingestr assets, so Kafka topics can be part of a governed Bruin pipeline.