Every source behind this page, graded by what it can prove. Filter by
kind. The full ledger, with one row per claim and the supporting quote copied verbatim,
ships beside this file as sources.md.
Postmortem
PagerDuty2025-09
August 28 Kafka Outages: What Happened and How We're Improving
Two incidents in one day caused by a producer instantiated per API request. The
transactional outbox prevented loss and converted the failure into a backlog plus
duplicate webhooks. Rare in publishing both the mechanism and the customer-visible
consequence of at-least-once delivery.
Carry forwardDurability changes the currency of the failure from lost data to delay and duplicates, and both are visible to your customers.
pagerduty.com/eng
Postmortem
Cloudflare2024-11
Cloudflare incident on November 14, 2024, resulting in lost logs
A blank configuration, a five-minute revert, and an untested fail-open path that
multiplied buffer count roughly fortyfold. The clearest public account of how the
buffering tier of an event pipeline becomes the loss mechanism.
Carry forwardLoad-test the fail-open state of every delivery component, because a failsafe never exercised at full scale is an untested system in the critical path.
blog.cloudflare.com
Postmortem
GitHub2018-10
October 21 post-incident analysis
Forty-three seconds of partition produced writes in two datacentres that could not be
reconciled automatically, and a day of degraded service. The definitive worked example
of what divergence costs once it exists.
Carry forwardWrite the diff-and-repair tool before you need it; the backlog outlives the incident and is where the next failure begins.
github.blog
Eng blog
Andreas Andreakis2026-08
Change-Data-Capture Doesn't Solve Dual-Writes
The author of Netflix's DBLog framework arguing that the remedy contains the disease.
Distinguishes retryable sink writes from non-retryable side effects, and points out
that replayable history has an expiry date.
Carry forwardAsk of every design: which of my second writes is retryable, and for how long is the evidence behind it retained.
aandreakis.com
Decision record
Apache Kafka2023-06
KIP-618: Exactly-Once Support for Source Connectors
Kafka's own admission that a source connector produces records and then writes its
offsets, and that the gap is unavoidable without framework changes. Includes ten
rejected alternatives, among them per-partition producers and record deduplication.
Carry forwardThe relay is a dual writer too. If your connector predates Kafka 3.3, its guarantee is at-least-once regardless of what the diagram says.
cwiki.apache.org
Decision record
Apache Kafka2024-07
KIP-939: Support Participation in 2PC
Two-phase commit returning to the stack that was built to avoid it, with the costs
stated openly: transactions never abort on their own, and read_committed consumers
block behind a prepared transaction until an operator intervenes.
Carry forwardAccepted is not shipped. Treat 2PC-with-Kafka as a design document until KAFKA-15370 closes.
cwiki.apache.org
Decision record
Apache Flink2023-08
FLIP-319: Integrate with Kafka's Support for Proper 2PC Participation
Flink's exactly-once Kafka sink bypasses the transaction protocol using Java
reflection and can lose data when Kafka aborts a checkpointed transaction on timeout.
Written by the maintainers, about their own code.
Carry forwardAn exactly-once label on a connector is a claim about a configuration, not a property of the system. Read the design doc before believing it.
cwiki.apache.org
Case study
Zalando2025-12
Contributing to Debezium: Fixing Logical Replication at Scale
Seven years of Postgres logical replication at scale, the WAL-growth failure on idle
databases, the driver fix, and the upstream decision to hard-code that fix off. Ends
with two new configuration options contributed back.
Carry forwardName one authority for stream position in writing, then check your framework's default agrees with you.
engineering.zalando.com
Case study
Shopify2021-03
Capturing Every Change From Shopify's Sharded Monolith
Log capture across more than 100 MySQL shards with real figures, plus the two honest
complaints: tables too large to snapshot, and breaking schema changes that couple every
downstream consumer to the internal data model.
Carry forwardCapturing business tables is free at the write path and expensive at the contract. Budget for a schema boundary you did not create.
shopify.engineering
Eng blog
Trade Republic2025-06
PostgreSQL + Outbox Pattern Revamped, Part 1
Query plans, heap fetch counts and execution times for a polled outbox before and
after partitioning. The most quantitatively honest outbox post found in this hunt.
Carry forwardPartition the outbox on published_at and truncate; a partial index plus delete degrades by five orders of magnitude under concurrency.
dev.to
Eng blog
Zapier2026
Lessons from using the outbox pattern at scale
A local sharded SQLite outbox on the emit path at fifteen thousand events per second,
the operational drag it produced, and the object-storage sidecar that replaced it. Rare
in describing a pattern being retired rather than adopted.
Carry forwardIf the bus already gives you a durable replayable backlog, a second durable store in front of it may be paying twice for one guarantee.
zapier.com/blog
Eng blog
Gunnar Morling2023-11
Can Debezium Lose Events?
The former Debezium lead answering the question directly: the tool does not lose
events, operations do, when the log is discarded before the reader catches up. Names
the exact parameters on MySQL and Postgres that set the boundary.
Carry forwardRecoverable downtime equals retention minus lag. It is the only capacity number this architecture really has.
morling.dev
Eng blog
SQUERundated
Stop overusing the outbox pattern
The dissent. David Leitner argues the outbox turns the database into the bottleneck of
an architecture adopted to avoid one, and proposes listen-to-yourself and event
sourcing as simpler answers for some cases. No page date, so treat as current opinion
rather than a dated position.
Carry forwardAsk whether the pattern is protecting a guarantee you actually need, or is arriving by default in a code review.
squer.io
Eng blog
Clear Street2020-10
Designing Clear Street's First Transactional Outbox Pattern
An outbox table read by Debezium in a brokerage, with the schema of the event table
spelled out and 2PC explicitly rejected. Promises a follow-up on what went wrong that
was never published.
Carry forwardCarry the Kafka partition key and the schema registry id as columns in the outbox row, so routing is data rather than code.
clearstreet.io
Source
Airbyte2026-07
Issue 82266: full reset never erases global CDC shared state
The offset-versus-slot divergence with an error string attached, plus a reset path that
cannot recover from it through the interface. Open, unassigned, with a workaround
supplied by the reporter.
Carry forwardTest your reset path on a pipeline whose stream catalogue has changed since creation. That is where the state machine breaks.
github.com/airbytehq
Source
Airbyte2023-10
Issue 31312: no records synced via CDC for large WAL
A 900 GB table, roughly 50 GB of log per day, and syncs that report success while
capturing nothing after a null resume position. Closed without a documented fix.
Carry forwardSend a heartbeat change through the real capture path and alarm on its absence; a green job is not evidence of capture.
github.com/airbytehq
Source
Debezium2026-08
PR 7687: DDD-53, a trigger-less outbox polling connector
A discussion-only proposal to detect row changes without a replication slot, closed
unmerged after a purely procedural response redirecting it to the design-documents
repository. No technical objection recorded.
Carry forwardThe middle ground between holding a slot and polling forever is unsettled. If neither fits your constraints, you are not doing it wrong.
github.com/debezium
Source
Airbnbrepo
SpinalTap
An independently built change-capture service, open sourced, with a source layer, a
Kafka destination and a ZooKeeper state store holding binlog file, position and next
position. Useful as convergent evidence for the reference architecture.
Carry forwardTwo teams who never spoke to each other both externalised the position record. That is a component, not an implementation detail.
github.com/airbnb
Source
Apache Kafka2026-08
KAFKA-15370: Support Participation in 2PC
The tracking issue for KIP-939. Created August 2023, last updated August 2026, status
open, resolution unresolved, fix version 4.5.0. Sub-tasks partially complete.
Carry forwardCheck the JIRA, not the KIP status, before putting a Kafka feature on a roadmap.
issues.apache.org
Paper
Netflix2020-10
DBLog: A Watermark Based Change-Data-Capture Framework
Andreakis and Papapanagiotou on interleaving chunked selects with log events using
watermarks, without locks, so a backfill does not stall the stream. In production at
Netflix across tens of microservices at the time of writing.
Carry forwardBackfill is a first-class component, not an emergency procedure. If your only snapshot mode locks the table, you have no recovery above a certain size.
arxiv.org/abs/2010.12597
Paper
CACM 62(5)2019-05
Online Event Processing: Achieving consistency where distributed transactions have failed
Kleppmann, Beresford and Svingen make the case that append-only logs can provide
atomicity and invariant enforcement without distributed transactions. The intellectual
foundation of the log-first default, and the sentence everybody quotes.
Carry forwardThe log-first argument is about ordering, not about atomicity of side effects. Read it before citing it in a review.
martin.kleppmann.com
Paper
Facebook, NSDI '152015
Wormhole: Reliable Pub-Sub to Support Geo-replicated Internet Services
Publishers read the storage systems' own transaction logs, delivery is at-least-once,
and the deployment moved 35 GB/s steady with bursts to 200 GB/s. Proof that the shape
in figure 2 is a decade old.
Carry forwardSize the pipeline for the recovery burst, not the steady state. The published ratio here is close to six to one.
blog.acolyer.org
Talk
QCon SF2019-11
Practical Change Data Streaming Use Cases With Apache Kafka and Debezium
Gunnar Morling's 65-slide deck. Slide 10 and slide 60 carry the line that became the
industry default position, and slides 41 and 42 give the outbox table design that most
implementations still follow.
Carry forwardThe slogan is sound and incomplete. It tells you to move the seam; it does not tell you where the seam lands.
speakerdeck.com
Talk
Current 20242024
Atomic Dual-write Recipes with Kafka Two Phase Commit (KIP-939)
Artem Livshits of Confluent presenting 2PC as the recipe that makes events commit to
Kafka if and only if changes commit to the database. Describes intent; the feature had
not shipped at the time of the talk or at the time of writing.
Carry forwardWhen a vendor session describes a guarantee, check which release it lands in before it enters your design.
current.confluent.io
Talk
Kafka Summit London2023
Exactly-Once, Again: Adding EOS Support for Kafka Connect Source Connectors
Chris Egerton, who implemented KIP-618, on why Connect lacked this support for
source connectors until version 3.3
and what it took to add it. Dates the gap
precisely.
Carry forwardIf your Connect deployment is older than 3.3, or your connector does not opt in, the pipeline is at-least-once end to end.
confluent.io
Vendor
Confluent2024-05
Understanding the Dual-Write Problem and Its Solutions
Wade Waldron's statement of the problem and the four-option menu: outbox, event
sourcing, listen-to-yourself, and the 2PC family. Useful as the canonical framing;
light on failure modes, as vendor material tends to be.
Carry forwardThe outbox is restricted to transactional databases
, which quietly rules it out for a large part of a modern estate.
confluent.io/blog
Vendor
Confluent Developercourse
Designing Event-Driven Microservices: The Listen to Yourself Pattern
Publish first, then consume your own event to update your database. Removes the dual
write and states the price plainly: a caller that reads immediately after writing
won't find what it is looking for
, and post-response validation failures create
inconsistencies the caller never learns about.
Carry forwardThis is the cheapest answer available, and it costs read-your-writes. That is an API contract decision, not an infrastructure one.
developer.confluent.io
Vendor
Apache Kafka2025-03
Apache Kafka 4.0.0 Release Announcement
Released 18 March 2025. The headline proposals are 848, 932, 966, 996, 890, 1102 and
653. KIP-939 is not among them, which is the cleanest way to date the gap between the
2PC design and its availability.
Carry forwardRelease notes are the cheapest fact-check available for a roadmap claim about an open-source feature.
kafka.apache.org