Lesson 16 · Senior CDC practice

Failure handling, poison records, and no-DLQ trade-offs

How to reason about connector failure modes, poison messages, task restarts, and what the generated-sink no-DLQ design gains and gives up.

Your win: explain the repo’s current failure-handling story honestly, including what auto-heal helps with, what it does not solve, and why no-DLQ is a real design trade-off.

Why this is one of the most senior conversations in the course

Some lessons are about knowing the system. This one is about being truthful about the system. That is why it feels more uncomfortable — and more valuable.

A lot of CDC explanations sound stronger than the real implementation. They mention retries, monitoring, and restarts, then quietly move past the harder question: what happens when one record is consistently bad enough to keep breaking the sink path?

In plain English Plain English: restarting a broken task is useful, but it is not the same as having a clean poison-record recovery path.

Why restartability and recoverability are not the same thing

This distinction is worth slowing down for. A restart path helps when the problem is transient: a task got stuck, a worker blipped, something recoverable happened. A poison-record path is about a different failure shape: the work keeps returning, and it keeps failing for a stable reason.

When you separate those two ideas, the repo’s current design becomes easier to explain honestly. It is operationally practical, but it does not yet offer the same kind of evidence-preserving recovery path that a real dead-letter design would.

The failure-handling rule A strong CDC design should preserve liveness, preserve failure evidence, and make recovery behavior explicit rather than merely restart-friendly.

What the current design is optimizing for

The current generated-sink path chooses simplicity: generated configs, auto-heal, readiness checks, and explicit honesty that no DLQ is configured. That is not automatically bad. It just means the trade-off should be named clearly instead of hidden behind optimistic language.

The best senior explanation sounds balanced: this setup is easier to operate and consistent with the rest of the platform model, but poison-record recovery is weaker than it would be with a dedicated dead-letter path.

Backend use case In this repo, generated sinks have no DLQ configured, while the control-plane and auto-heal paths focus on restartability, readiness, and convergence rather than rich per-record failure parking.
Common mistake Treating restart automation as if it fully solved poison-record handling.
Read this next

JDBC sink behavior and repo operations together

Use the sink docs with the repo map so the no-DLQ gap stays attached to the real control-plane and monitoring story.

JDBC sink connector
Repo CDC map

Check yourself (from memory)

Q1. What is the clearest senior description of the no-DLQ trade-off here?

Simplicity is real, but so is the observability and recovery gap.
Why is auto-heal not the same thing as a DLQ?
recall, then click to reveal
Because auto-heal restarts tasks after failure, but it does not preserve a clean poison-record path or provide a dedicated place to inspect and recover bad records safely.
Want a “how would you explain the no-DLQ trade-off in an interview?” drill? Ask me.

Sources. JDBC sink docs; repo CDC map.