15. When to use CDC, and when not
Debezium · 15. When to use CDC, and when notCDC is powerful and it is not free. This chapter is about telling the cases apart.
The one question
Section titled “The one question”Do other systems need to know about changes to this database, reliably, and soon?
All three words matter.
"other systems" → if only your own application needs it, just query the table "reliably" → if occasional loss is acceptable, polling is simpler "soon" → if daily is fine, a scheduled export is simplerYes to all three → CDC, and probably Debezium.
No to any of them → something simpler exists, and simpler is worth a great deal given chapters 13 and 14.
CDC vs polling
Section titled “CDC vs polling” POLLING CDC ───────────────────── ──────────────────── MISSES DELETES sees deletes misses intermediate every change states needs a reliable needs a log updated_at query load on the source log-read load latency = poll interval seconds nothing to operate a pipeline, a slot, a DBA relationship ✓ trivially simple ✗ chapters 13, 14Polling is genuinely fine when: you only need current state, deletes do not happen or do not matter, minutes of latency are acceptable, and the table is small enough that the query is cheap.
That describes a lot of internal tooling, and reaching for CDC there is over-engineering.
Polling breaks down when deletes matter, you need every intermediate state, the table is large enough that the query hurts, or the commit-ordering boundary problem (chapter 1) starts losing rows — which it will, quietly, at scale.
CDC vs triggers
Section titled “CDC vs triggers” TRIGGERS CDC ───────────────────── ──────────────────── INSIDE your transaction outside it doubles write volume reads an existing log one per table, forever one connector still needs delivery delivery included ✓ no new infrastructure ✗ new infrastructure ✓ works on any database ✓ works on the supported onesTriggers plus a polled audit table is a legitimate small-scale answer — no Kafka, no slot, no Connect cluster. It costs write latency and it does not scale, but for a modest system it is a lot less machinery.
Choose CDC when the write-path cost matters, or when you have outgrown “one more trigger”.
CDC vs application events
Section titled “CDC vs application events”The comparison that matters most, because it is the real alternative.
APPLICATION EVENTS CDC (publish from code) ───────────────────── ──────────────────── ✓ events you DESIGNED ✗ row diffs ✓ domain language ✗ internal schema ✓ intent is explicit ✗ inferred downstream ✗ THE DUAL-WRITE PROBLEM ✓ atomic with the (chapter 1) commit ✗ a forgotten code path ✓ nothing can be is silent missedBoth columns have a fatal entry. Application events have the right shape and no delivery guarantee; CDC has the guarantee and the wrong shape.
The outbox pattern (chapter 10) is not a compromise between them — it is both. The event you designed, written in the same transaction, delivered by CDC.
→ If you are choosing between "publish events from the application" and "CDC", the answer is usually THE OUTBOX.CDC vs dual writes
Section titled “CDC vs dual writes”Not a real option, and worth stating once. Chapter 1’s argument: there is no correct ordering. Every dual-write system is a system with a known, unfixable inconsistency window, and the only question is how often it bites.
Debezium vs Fivetran, Airbyte and the managed services
Section titled “Debezium vs Fivetran, Airbyte and the managed services” DEBEZIUM MANAGED (Fivetran, Airbyte Cloud, AWS DMS, GCP Datastream) ───────────────────── ──────────────────── free, Apache 2.0 per-row or per- connector pricing you run it they run it you own the slot risk they own it — MOSTLY. read on. any sink their catalogue full control of the limited shaping event shape ← chapters 13, 14 are ← a support contract your jobThe honest framing: you are paying for someone else to have read chapter 13.
USE A MANAGED SERVICE WHEN ✓ moving data to a warehouse is the whole job ✓ you have no capacity to operate a pipeline ✓ the source and destination are both on their list ✓ per-row pricing is acceptable at your volume
USE DEBEZIUM WHEN ✓ you want events, not just replication ✓ the destination is a service, a cache, a search index — not a warehouse ✓ you need the outbox pattern ✓ volume makes per-row pricing painful ✓ you want to control the event shape ✓ you already run KafkaOne caveat about managed services worth knowing: several of them use logical replication slots too. The slot risk of chapter 2 does not disappear because a vendor is running the connector — a paused or failed managed pipeline can still fill your PostgreSQL disk. Ask, and monitor the slot yourself either way.
Many teams run both: a managed pipeline for warehouse loading, Debezium for service integration. That is a sensible division rather than duplication.
Debezium vs the database’s own tools
Section titled “Debezium vs the database’s own tools” POSTGRES LOGICAL REPLICATION ✓ built in, no extra system ✗ target must be another PostgreSQL → REPLICATION, not integration. chapter 1's distinction.
MONGODB CHANGE STREAMS, DIRECTLY ✓ no Debezium at all — your app opens a change stream ✓ genuinely simple for ONE consumer ✗ you own resume tokens, retries, fan-out, and every consumer opens its own stream against the database → good for one consumer, poor for many
MySQL BINLOG READERS (maxwell, etc.) ✓ lighter than Connect ✗ narrower ecosystem, fewer sinksThe pattern: native tools are excellent for one consumer and poor for many. Debezium’s value grows with the number of things that need the changes, because the broker turns one read of the log into N deliveries.
If exactly one system needs the changes and it is your own service, the native tool — or Debezium’s embedded engine (chapter 3) — may be all you need.
Debezium vs Flink CDC
Section titled “Debezium vs Flink CDC” FLINK CDC uses Debezium underneath, as a library, inside a Flink job.
✓ no Kafka, no Connect ✓ read, transform and sink in one job ✓ Flink's checkpointing gives you exactly-once into the sink ✗ ONE JOB READS THE LOG PER PIPELINE → two Flink jobs on one table means two slots, two log reads ✗ no replayable topic in the middle → a new consumer means a new snapshotFlink CDC is excellent for a single, well-defined pipeline — database to lake, database to search index, with transformation on the way.
Debezium into Kafka is better when several things need the changes, because chapter 12’s bootstrap-from-a-compacted-topic property is worth a great deal and Flink CDC does not have it.
When CDC is the wrong choice
Section titled “When CDC is the wrong choice” ✗ ONLY ONE CONSUMER, AND IT IS YOUR APP → query the table. or a change stream. or the embedded engine.
✗ DAILY BATCH IS FINE → a scheduled export. seriously. most warehouse loading is this.
✗ NOBODY WILL OWN THE OPERATIONS → chapter 13 is real work with a real on-call cost, and chapter 14's first failure takes down your database. a managed service, or polling.
✗ THE DBA TEAM WILL NOT ENGAGE → this is a veto, not an obstacle. CDC without database-side monitoring is an incident waiting.
✗ YOU CANNOT CHANGE THE DATABASE CONFIGURATION → wal_level, binlog_format, CDC enablement. no configuration, no CDC.
✗ THE SCHEMA CHANGES CONSTANTLY AND CONSUMERS CANNOT KEEP UP → the outbox, or nothing.
✗ SUB-MILLISECOND PROPAGATION REQUIRED → CDC is seconds. that is fast, and it is not synchronous. if a read must see the write immediately, read the source.That last one is worth emphasising. CDC is eventually consistent by construction. A downstream system is always slightly behind, and a user who writes and then immediately reads from the derived system will sometimes see stale data. Design for it, or do not derive that view.
When CDC is obviously right
Section titled “When CDC is obviously right” ✓ several systems need the same changes ✓ deletes matter ✓ you need every intermediate state, not just current ✓ the dual-write problem is already hurting you ✓ a search index or cache keeps drifting from the database ✓ you want an audit trail of what actually happened ✓ you are building service integration and want it atomic → the outbox ✓ you need to replay history into a new consumerThe honest summary
Section titled “The honest summary”Debezium’s idea is excellent and slightly unfair: the database was already doing the hard part. The write-ahead log exists for crash recovery and replication; CDC is the observation that it is also a complete, ordered, durable event stream that nobody was using.
What you pay for it is coupling. The pipeline is now part of the database’s operational surface — most sharply on PostgreSQL, where a stopped consumer can take the database down. That is a genuinely serious cost, and it is the reason chapters 13 and 14 are as long as they are.
What you get is the only architecture that makes “this change reached every system” true without distributed transactions. For a system of any size with more than one datastore, that is worth the cost.
And the refinement worth ending on is the outbox. Raw CDC gives you the guarantee with the wrong shape; the outbox gives you the guarantee with a shape you designed. If CDC is going to be a long-lived part of your architecture, that is where it should end up.
What to take from this chapter
Section titled “What to take from this chapter”- The question is: do other systems need changes, reliably, and soon? All three words matter, and a no to any one of them means something simpler exists.
- Polling is genuinely fine for small internal tooling where deletes do not matter and minutes are acceptable. It breaks on deletes, intermediate states, scale, and commit ordering.
- Triggers plus a polled table is a legitimate small-scale answer that costs write latency.
- Application events have the right shape and no guarantee; CDC has the guarantee and the wrong shape. The outbox is both — and is usually the answer when you are choosing between them.
- Managed services mean paying someone to have read chapter 13 — but the slot risk does not disappear just because a vendor runs the connector.
- Native tools are excellent for one consumer and poor for many. Debezium’s value grows with the number of consumers.
- Flink CDC is better for one pipeline; Debezium into Kafka is better when several things need the changes, because of bootstrap-from-a-compacted-topic.
- CDC is wrong when there is one consumer, when daily batch is fine, when nobody will own the operations, or when the DBA team will not engage — that last one is a veto.
- CDC is eventually consistent by construction. A read-after-write against a derived system will sometimes be stale.
- The cost is coupling to the database’s operational surface. The benefit is the only architecture that makes “it reached every system” true without distributed transactions.
Next: the cheat sheet — configuration, event shapes, signals and diagnostics, on one page.