Change Data Capture (CDC) feels like a cheat code.
I remember the first time I tried it, we had a legacy service, and the idea of streaming database changes without touching the code felt like magic.
And while it works, there are trade-offs you should know before jumping in.
Here are 7 lessons I’ve learned the hard way:
IcePanel’s a collaborative diagramming and modelling tool for designing software architecture. Create interactive and layered views for different stakeholders, based on a single source of truth.
1. Event Granularity: Business Fact vs. Domain Model
CDC streams are tied to tables, not to business events.
Imagine a customer places an order:
orders
table gets a new row.order_items
table inserts multiple rows.payments
table updates with a pending transaction.
CDC faithfully emits three different low-level events.
But what consumers actually wanted was a single, meaningful business event:
{
“event”: “OrderPlaced”,
“orderId”: “123”,
“total”: 89.50,
“items”: [ ... ]
}
Instead, they get a stream of row changes and have to reconstruct the business fact themselves. This adds complexity, invites inconsistent interpretations, and turns your supposedly decoupled consumers into fragile data archaeologists.
2. Database Schema Coupling
Your schema becomes your contract.
Merge two tables? Consumers, depending on the old streams, break.
Split one table into many? You may need to create new streams, forcing everyone to update.
A schema change that should be local to a team now requires cross-team coordination. The more consumers you have, the harder this becomes.
The result: your producer service loses autonomy. Every schema tweak becomes a release-management nightmare.
3. Sensitive Data Exposure
CDC publishes the full row by default. That often includes fields like:
Credit card numbers
Social Security numbers
Internal audit fields
Now every downstream consumer sees them.
You can filter or encrypt, but that creates a new problem: some consumers need that data, some don’t. Which means custom filtering logic, duplicated pipelines, or complicated access policies.
Instead of protecting sensitive fields at the source, CDC spreads the risk system-wide.
4. Handling Relational Data
Most real-world domains aren’t flat. They have relationships.
Orders belong to Customers.
Orders contain Items.
Items reference Products.
CDC splits these into different streams (orders
, customers
, products
). Consumers now have to:
Subscribe to multiple streams.
Perform joins.
Reconstruct context before doing anything useful.
Each consumer ends up reimplementing business logic that should have stayed in the producer service. This increases bugs, documentation debt, and wasted effort.
5. Configuration Complexity
CDC isn’t “flip a switch and done.”
You have to configure:
Which tables to capture.
How to serialize events.
What schema format to use.
How to handle deletes and updates.
Misconfigure one setting, and you risk malformed events or silent data loss. Consumers will keep processing, unaware they’re working with incomplete or corrupted data.
6. Database Migration Challenges
Switch databases, say, from MySQL to PostgreSQL, and you’ll quickly discover that CDC tools don’t guarantee consistent event formats.
Column types differ. Timestamps look different. Even the order of fields can change.
That means every consumer must adapt. A migration that should be a producer concern suddenly becomes an organization-wide coordination project.
7. Operational Overhead
The CDC processor (Debezium, GoldenGate, etc.) isn’t free. It’s another critical moving part in your system.
If it crashes, your event stream stalls.
If it lags, consumers drift behind real time.
If it silently drops changes, producers and consumers fall out of sync.
And then comes the biggest question: who owns it?
The producer service team?
The DevOps/SRE group?
A shared data engineering team?
Without clear ownership and robust observability, CDC can become your weakest link.
The Hidden Complexity of CDC
On paper, CDC decouples producers from event publishing.
In practice, it couples consumers to the producer’s database design.
Consumers deal with row-level noise, not meaningful business events.
Schema changes ripple across every service.
Sensitive data spreads far too easily.
Operations become fragile and political.
What started as a shortcut to avoid writing event code ends up creating a web of dependencies that slows everyone down.
An Alternative Path: Transactional Outbox?
CDC has its place, but for most event-driven architectures, a Transactional Outbox is safer.
Instead of exposing table changes, the producer writes business events into an outbox table as part of its transaction. A relay process then publishes them to the event bus.
The result:
Events are high-level facts (
OrderPlaced
), not schema leaks.Schema changes stay internal.
Producers own their contracts.
Consumers stay shielded.
Takeaways
CDC feels “free,” but it’s expensive for consumers.
It leaks domain internals, exposes sensitive data, and ties everyone to your schema.
It creates operational risks with an extra moving part in your pipeline.
For autonomy and clarity, favor business events via a Transactional Outbox.
That said, CDC is still one of my favorite tech for Legacy integration and analytics.
Every row change is data. Every business fact is an event. Know the difference.
Until next time,
— Raul
System Design Classroom is a reader-supported publication. To receive new posts and support my work, consider becoming a paid subscriber.