Developer Tools

Kafka Delivery Semantics: Where Exactly-Once Stops

Understand commit timing, transactional scope and why external effects still need idempotency.

AiFolder Editorial Team

AiFolder Editorial Team

5 min read

Updated Oct 9, 2026

A red message envelope traverses three tactile checkpoints, a duplicate transparent echo stopped at the final brass gate, delivery and deduplication
Original AiFolder editorial illustration

Name the boundary of the guarantee

At-most-once allows missed work, at-least-once allows repeated work, and exactly-once requires a precisely defined scope. Kafka transactions can coordinate Kafka records and consumed offsets; they do not automatically include an arbitrary database or HTTP service. The official design document is the starting point for that boundary.

Consider consuming an order event and sending an email. The email provider may accept the message while the consumer crashes before committing its offset. Redelivery is correct from Kafka's perspective, but an unprotected second email is a duplicate business effect.

Three illustrative timelines

Commit first: read event → commit offset → send email. A crash between commit and send loses the effect.

Effect first: read event → send email → commit offset. A crash between send and commit can repeat the effect.

Transactional Kafka output: read event → begin transaction → produce derived Kafka records → send consumed offsets to transaction → commit. Properly configured downstream readers exclude aborted output. This still says nothing about an email sent outside that transaction.

A database write succeeds before the offset is committed

A consumer reads a payment event and updates a reporting database. It crashes before committing its offset. After restart, the same record is delivered again because the committed position still precedes it. That replay is a normal consequence of the chosen boundary; it becomes a problem only if the database update blindly increments the total again. The durable destination needs a way to recognize the event or apply a versioned business update.

Store a deduplication identifier with the reporting mutation in one transaction where possible. A separate insert performed before or after the mutation leaves another crash window. Decide what happens when the same event identifier arrives with different content; silently accepting it can hide upstream corruption. For an email or third-party API call, a local deduplication table may still leave ambiguity between the remote effect and the local completion marker. Use a destination-supported stable operation identity or an explicit reconciliation path. Delivery semantics must be described across the full effect boundary, not inferred from a producer setting.

A database write succeeds before the offset is committed: Read record → Write database → Process crashes → Replay record
A database write succeeds before the offset is committed. Original AiFolder explanatory diagram; illustrative workflow.

Name the boundary of an exactly-once claim

An idempotent producer addresses duplicate append behavior from producer retries under its documented conditions. Kafka transactions can coordinate writes to Kafka topics and consumed offsets for a Kafka processing pipeline. Those capabilities do not automatically make a bank transfer, database update or email send part of the same transaction. A claim about exactly-once processing should name both the source and the destination, the reader isolation behavior and the failures it covers.

For a stream transformation that only produces new Kafka records, the transactional design can keep output and offset progress together. For a database sink, use the database's own atomicity and a stable record identity or connector guarantee appropriate to that sink. Do not combine an independent database commit and Kafka offset commit and label the pair atomic. The important product question is which business effect can repeat, be lost or remain ambiguous. A useful architecture diagram marks every durable boundary and the coordination mechanism crossing it; a single exactly-once badge obscures where recovery is still the application's responsibility.

Name the boundary of an exactly-once claim: Producer retry → Kafka transaction → Database effect → External API
Name the boundary of an exactly-once claim. Original AiFolder explanatory diagram; illustrative workflow.

Producer deduplication is only one part

An idempotent producer protects against particular duplicate writes caused by producer retries. Business-level retries can still generate distinct events. If the application creates two event IDs for one logical order, transport deduplication cannot infer that the second order event was accidental.

Use a stable business operation identifier through the workflow. For database consumers, a unique processed-event record and the business update can share a database transaction. Repeated delivery then becomes a known duplicate instead of a second mutation. External providers may support their own idempotency keys; follow their actual retention and mismatch rules.

Make the configuration explicit

For a transactional read-process-write Kafka workflow, document producer transaction identity, consumer isolation and offset handling. Consult the producer configuration reference and consumer configuration reference for the client and broker version in use. A configuration name copied from a tutorial is not proof that every participant honors the intended semantics.

Verify the failure window

Create a fixture with known operation IDs and deliberately stop the consumer after its effect. Restart and compare input IDs, durable results and offsets. Also test a transaction abort and a producer restart. Counting messages alone is insufficient; inspect whether each business operation occurred once.

Operational recovery must include poisoned records, repeated failures and a controlled replay procedure. A dead-letter topic records a failure for later investigation; it does not make an unfinished order successful.

Read idempotency keys and Kafka consumer groups for the surrounding design. No throughput measurements or universal exactly-once claim are made in this guide.

Verify the effect, not only the consumer counter

A delivery verification plan should interrupt the consumer after it has received a record, after a destination mutation and after committing progress. Use known event identifiers and compare durable business results with those identifiers. A consumer dashboard showing one successful callback does not prove that a remote side effect occurred once; the callback and the effect can have different failure boundaries. Retain enough correlation data to explain an ambiguous case without guessing from timestamps.

Also test duplicate delivery from the source and a delayed response from the destination. Keep retries bounded and make poison records observable rather than allowing an endless loop to block a partition silently. For transactional Kafka output, verify that downstream readers use the intended isolation behavior. For database output, verify the deduplication rule under simultaneous attempts, not only sequential replay. Document the residual failure cases and recovery procedure beside the chosen configuration. This produces a precise operational guarantee that survives a restart and gives the team a concrete way to challenge any broader claim.

Verify the effect, not only the consumer counter: Inject crash → Restart consumer → Inspect output → Reconcile identities
Verify the effect, not only the consumer counter. Original AiFolder explanatory diagram; illustrative workflow.

Further reading for these examples

Topics

AiFolder Editorial Team

Written by

AiFolder Editorial Team

Practical technology guides with clear sources, examples and limitations.

Continue reading

More articles

View all