Scenario 01.1.3 · acks trade-off
Kafka acks=0 vs acks=1 vs acks=all on a degraded ISR
Same degraded ISR: acks=all refuses to commit; acks=1 acks on the leader alone; acks=0 fire-and-forget, silently lost once the leader dies.
Run this scenario in the playgroundCluster ready - acks=all, RF=3, min.ISR=2. t+0.000s
Open at this step: step 1, Cluster ready - acks=all, RF=3, min.ISR=2broker-3 down - ISR shrinks to 2. t+3.050s
Open at this step: step 2, broker-3 down - ISR shrinks to 2broker-2 down - ISR shrinks to 1 (below min.ISR). t+6.050s
Open at this step: step 3, broker-2 down - ISR shrinks to 1 (below min.ISR)acks=all produce blocked - NotEnoughReplicas. t+9.200s
Durability wins: acks=all refuses to ack below min.insync.replicas.
Open at this step: step 4, acks=all produce blocked - NotEnoughReplicasacks lowered to 1 (a real producer is recreated). t+12.100s
Open at this step: step 5, acks lowered to 1 (a real producer is recreated)acks=1 acks on the leader alone. t+13.200s
Availability wins: acked, but the record sits only on the leader (HW pinned) - lost if the leader fails.
Open at this step: step 6, acks=1 acks on the leader aloneacks=0 fire-and-forget - sent, never acknowledged. t+16.200s
Speed wins: acks=0 gets no acknowledgement at all. The leader appended the record, but the producer never waits to hear - status is "sent", not acked.
Open at this step: step 7, acks=0 fire-and-forget - sent, never acknowledgedbroker-1 down - partition leaderless (no replica left to elect). t+19.600s
Open at this step: step 8, broker-1 down - partition leaderless (no replica left to elect)acks=0 into a leaderless partition - lost. t+22.200s
Data loss: with no leader, A4 never leaves the producer. The simulator drops it and still shows "sent"; a real producer holds it in its buffer and fails it with a TimeoutException after delivery.timeout.ms (120 s), even at acks=0.
Open at this step: step 9, acks=0 into a leaderless partition - lostWhat you start with
This scenario puts all three acks levels side by side against the SAME degraded cluster. After two brokers are killed the ISR drops below min.insync.replicas, then the producer writes a record at acks=all, is switched to acks=1, then to acks=0 (the simulator changes acks live; a real producer is recreated with the new setting) - so you can compare how each setting reacts to a partition that can no longer satisfy durability.
Step by step
- Cluster ready - acks=all, RF=3, min.ISR=2 t+0.000s Open at this step: step 1, Cluster ready - acks=all, RF=3, min.ISR=2
- broker-3 down - ISR shrinks to 2 t+3.050s Open at this step: step 2, broker-3 down - ISR shrinks to 2
- broker-2 down - ISR shrinks to 1 (below min.ISR) t+6.050s Open at this step: step 3, broker-2 down - ISR shrinks to 1 (below min.ISR)
- acks=all produce blocked - NotEnoughReplicas t+9.200s Durability wins: acks=all refuses to ack below min.insync.replicas. Open at this step: step 4, acks=all produce blocked - NotEnoughReplicas
- acks lowered to 1 (a real producer is recreated) t+12.100s Open at this step: step 5, acks lowered to 1 (a real producer is recreated)
- acks=1 acks on the leader alone t+13.200s Availability wins: acked, but the record sits only on the leader (HW pinned) - lost if the leader fails. Open at this step: step 6, acks=1 acks on the leader alone
- acks=0 fire-and-forget - sent, never acknowledged t+16.200s Speed wins: acks=0 gets no acknowledgement at all. The leader appended the record, but the producer never waits to hear - status is "sent", not acked. Open at this step: step 7, acks=0 fire-and-forget - sent, never acknowledged
- broker-1 down - partition leaderless (no replica left to elect) t+19.600s Open at this step: step 8, broker-1 down - partition leaderless (no replica left to elect)
- acks=0 into a leaderless partition - lost t+22.200s Data loss: with no leader, A4 never leaves the producer. The simulator drops it and still shows "sent"; a real producer holds it in its buffer and fails it with a TimeoutException after delivery.timeout.ms (120 s), even at acks=0. Open at this step: step 9, acks=0 into a leaderless partition - lost
The takeaway
acks is a sliding durability-vs-latency dial: acks=all refuses to commit when the ISR is too small, acks=1 acknowledges on the leader alone without committing, and acks=0 never waits and loses the write silently once that leader dies.
Configs in this scenario
-
acksHow many replicas must have a write before the producer counts it as sent: 0 (none), 1 (the leader only) or all (every in-sync replica, the default, and required for idempotence). How acks works -
min.The fewest in-sync replicas, leader included, that must have a write for an acks=all produce to succeed (default 1); with fewer in the ISR the leader rejects the write with NOT_ENOUGH_REPLICAS. How min.insync.replicas worksinsync. replicas -
delivery.The upper bound on reporting success or failure after send() returns, covering the wait in a batch, the wait for the acknowledgement and every retry (default 120000, 2 minutes); it should be at least request.timeout.ms plus linger.ms.timeout. ms
Embed this scenario
Paste this into a blog post, a course page or your team's docs. The scenario plays inside your page, and the link under it points readers to this walkthrough.
<iframe src="https://monedula.dev/kafka-simulator/embed/?scenario=01.1.3" title="Kafka Simulator: acks trade-off" width="100%" height="520" style="border:1px solid #d0d0d0;border-radius:8px" loading="lazy"></iframe>
<p><a href="https://monedula.dev/kafka-simulator/scenarios/acks-tradeoff/">Kafka acks=0 vs acks=1 vs acks=all on a degraded ISR</a></p> Further reading
Troubleshooting
- NotEnoughReplicasException in Kafka: causes and fixes
- Kafka offline partitions with no leader: causes and fixes
More in Producers & EOS
- Kafka producer acks=0: fire and forget, silent data loss
- Kafka producer acks=1: acknowledged by the leader only
- Kafka acks=1 data loss: min.insync.replicas does not help
- Kafka linger.ms vs batch.size: when the producer sends
- Kafka producer partitioners: keyed, round-robin and sticky
- Kafka compression.type: fewer, larger producer batches
- Kafka buffer.memory and max.block.ms: producer backpressure
- Kafka idempotent producer: retrying NOT_ENOUGH_REPLICAS
- Kafka enable.idempotence=false: a retry writes a duplicate
- Kafka idempotent producer dedup vs a plain producer
- Kafka max.in.flight.requests.per.connection and ordering