Durability is four knobs, not one — acks=all, min.insync.replicas and unclean.leader.election
acks=all only guarantees no loss when min.insync.replicas >= 2 and unclean.leader.election=false; otherwise ISR can shrink to {leader} and 'all' silently means one.
ISR decides commit, the controller decides leadership. Now the four knobs that decide what 'durable' actually means — and how a wrong combination turns 'acks=all' into 'acks=one' without any error.
Scene 05
Durability is four knobs, not one
- Watch
- Try it
- Predict
- Capture
Default config: RF=3, min.insync.replicas=2, acks=all, unclean.leader.election=off. Producer sends, all three replicas append, leader acks. The downstream reader sees a fully replicated log — a leader crash here loses zero acked writes.
Highlighted lines are the ones running in the diagram right now.
def send(record):leader = metadata.leaderFor(record.partition)resp = leader.produce(record, acks=cfg.acks)if cfg.acks == 0:return # fire-and-forget, no waitif cfg.acks == 1:return resp # leader-only ack# acks == 'all': leader replies only after the# broker-side commit gate has accepted the record.return resp
def onProduce(record):self.log.append(record) # leader appends firstif cfg.acks != 'all':return Ack() # no ISR check on acks=0/1if len(ISR) < cfg.min_insync_replicas:raise NotEnoughReplicas(isr=len(ISR), required=cfg.min_insync_replicas,)waitForFetch(record.offset, replicas=ISR)self.hw = min(leo[r] for r in ISR)return Ack()
def maybeUncleanElect(partition):if len(ISR) > 0:return promote(pickFromISR())if not cfg.unclean_leader_election_enable:partition.state = UNAVAILABLEreturn None # KIP-106 defaultcandidate = pickAnyLiveReplica()candidate.epoch += 1 # bumps leader epochreturn promote(candidate)
Where this sits in Build Kafka
Scene 05 of 13, in the Write side act — Partitioning, replication, and durability knobs.. acks, min.insync.replicas, RF, unclean — and how 'all' silently means one.
Up next. Log compaction — keep the last value per key. Compacted topics turn the log itself into a state store, and underpin __consumer_offsets, Streams k-tables, and CDC sinks.
Designs that use this
- Twitter / X TimelinePush or pull? Both. The canonical fanout problem.
- Uber / Lyft — Match Drivers and RidersMatch a rider to the closest acceptable driver in under 3 s. Geohash, S2, surge.
- Slack / DiscordChannels and history. Push or pull — and how a hot-channel fanout doesn't melt the gateway.
- WhatsApp / MessengerHundreds of millions of long-lived sockets, sub-second 1:1 + group delivery, E2E-encrypted, multi-device, multi-region active-active.