Kafka — Delivery Semantics, Exactly-Once & Producer Back-Pressure (Deep Dive)
Kafka — Delivery Semantics, Exactly-Once & Producer Back-Pressure
The guide covers Kafka's storage, durability, rebalancing, and partition model. This page fills the producer/delivery side an interviewer drills: how at-most / at-least / exactly-once fall out of mechanics (not marketing), how the idempotent producer and transactions actually achieve exactly-once, what happens when the producer buffer fills, and the ordering-vs-throughput knob that silently reorders your writes.
1. Delivery semantics come from offset-commit timing
The three semantics aren't modes you pick from a menu — they're consequences of when the consumer commits its offset relative to processing:
- At-most-once: commit the offset before processing. If you crash after committing but before finishing the work, the message is never reprocessed — lost. No duplicates, possible loss.
- At-least-once (the default): commit after processing. Crash after the work but before the commit, and on restart you reprocess from the last commit — duplicate. No loss, possible duplicates. This is why the standard advice is "make your consumer idempotent."
- Exactly-once: requires making the process-and-commit atomic — see §2.
2. How exactly-once is actually achieved
Kafka's exactly-once is two mechanisms:
- Idempotent producer (
enable.idempotence=true): each producer gets a producer id (PID) and stamps every message with a monotonic sequence number per partition. The broker tracks the last sequence it accepted and discards duplicates — so a producer retry after a network blip doesn't write the record twice. This removes duplicates on the write path. - Transactions: a producer can atomically write to multiple partitions and commit consumer offsets in one transaction. Consumers reading with
isolation.level=read_committedonly see messages from committed transactions. This is what makes a read-process-write loop (consume from A, produce to B, commit offset) exactly-once end-to-end: either all three commit or none do. Without transactions you get at-least-once and must dedup downstream.
Key nuance for interviews: "exactly-once" is exactly-once processing within Kafka's boundary — a side effect to an external system (an email, a non-transactional DB write) still needs its own idempotency key. Kafka can't make an email un-sent.
3. Producer back-pressure: when the buffer fills
The producer doesn't send each record synchronously — it accumulates them in an in-memory buffer (buffer.memory, default 32 MB), batched by batch.size and linger.ms, and a background thread ships batches. If the broker is slow or down and the buffer fills, send() blocks — up to max.block.ms, after which it throws a TimeoutException. That block is the write-side back-pressure: it propagates broker slowness back into your application thread instead of silently dropping data or growing memory unbounded. The design decision you must make: on that timeout, do you drop, retry, or shed load upstream? Ignoring it turns a slow broker into an app-wide stall or OOM.
4. In-order vs throughput: the silent reordering
For throughput you want multiple in-flight requests (max.in.flight.requests.per.connection > 1) so the producer isn't waiting for each ack. But combine that with retries and you get reordering: if request 1 fails and is retried while request 2 already succeeded, message 2 lands before message 1 — order broken within the partition (Kafka only orders within a partition to begin with). The remedy is not to set in-flight to 1 (kills throughput): enabling enable.idempotence lets the broker use the sequence numbers to reject out-of-order batches and preserve order while still allowing up to 5 in-flight requests. So idempotence buys you both ordering and throughput — another reason it's the modern default.
5. Fan-out tail latency and why idempotency is forced
A consumer group scales by adding consumers up to the partition count, and downstream fan-out (one event → many handlers) is common. Two consequences: (1) any operation that waits on all fan-out targets inherits the slowest one — the tail-latency amplification law (p99 of the whole is driven by the worst participant, worsening with fan-out width). (2) Rebalances and at-least-once mean a partition's messages will be reprocessed at some point (a consumer dies mid-batch, its partitions move, the new owner reprocesses from the last commit). Therefore consumer handlers must be idempotent — reprocessing is not an exceptional case, it's a guaranteed eventuality. Use a dedup key (the message's offset or a business id) so a replay is a no-op.
Judgment layer & takeaways
- Semantics: default at-least-once + idempotent consumer covers the vast majority — reach for full transactions only when you truly need atomic read-process-write and can pay the coordination cost/latency.
- enable.idempotence: effectively free correctness (dedup + ordering) with in-flight throughput — leave it on.
- Back-pressure: set
max.block.msdeliberately and decide the timeout policy; never treat the producer buffer as infinite. - Idempotency: not optional at scale — rebalances guarantee reprocessing, so design every consumer to tolerate replays.
Re-authored/Deepened for this guide.
🤖 Don't fully get this? Learn it with Claude
Stuck on Kafka — Delivery Semantics, Exactly-Once & Producer Back-Pressure (Deep Dive)? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Build the mental picture, not memorization.
I just read a lesson on **Kafka — Delivery Semantics, Exactly-Once & Producer Back-Pressure (Deep Dive)** (System Design) and want to truly understand it. Explain Kafka — Delivery Semantics, Exactly-Once & Producer Back-Pressure (Deep Dive) from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Socratic — adapts to where you're stuck.
Teach me **Kafka — Delivery Semantics, Exactly-Once & Producer Back-Pressure (Deep Dive)** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Active recall exposes what you missed.
Quiz me on **Kafka — Delivery Semantics, Exactly-Once & Producer Back-Pressure (Deep Dive)** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Intuition + hook + flashcards for long-term memory.
Help me remember **Kafka — Delivery Semantics, Exactly-Once & Producer Back-Pressure (Deep Dive)** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.