Skip to content

15. When to use CDC, and when not

CDC is powerful and it is not free. This chapter is about telling the cases apart.

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
simpler

Yes 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.

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, 14

Polling 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.

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 ones

Triggers 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”.

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 missed

Both 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.

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 job

The 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 Kafka

One 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.

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 sinks

The 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.

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 snapshot

Flink 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.

✗ 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.

✓ 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
consumer

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.

  • 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.

Written by Sepuri Sai Krishna

© 2026CC BY 4.0Source