skip to content

min.insync.replicas and the acks=all Contract

The broker-side durability contract: min.insync.replicas with acks=all, and what happens when the ISR shrinks below the floor. Interviewers ask why replication factor 3 with min.isr 2 is the standard answer.

part ofApache Kafkaoverview, primer and where to startread it →
on this pageshow

questions

5

What does the broker-side config min.insync.replicas do, and how does it relate to acks=all?

level: juniorimportance: must knowfreq 70%

answer

  1. ISR floor for acks=all writes
  2. ignored unless acks=all
  3. leader rejects with NotEnoughReplicasException
  4. RF is ceiling, ISR is live count
  5. contract: producer asks, broker enforces

basics

~10 s

min.insync.replicas sets the minimum number of in-sync replicas that must acknowledge a write before the broker accepts it. It only takes effect when the producer uses acks=all; otherwise the broker ignores it.

solid answer

~40 s

min.insync.replicas is a broker/topic config that defines the floor of in-sync replicas (ISR) required for a write to succeed. It only matters when the producer sends with acks=all (also written acks=-1): in that case the leader will not acknowledge a produce request until at least min.insync.replicas members of the ISR have persisted the record. If fewer replicas are in-sync than the floor, the leader rejects the write with NotEnoughReplicasException (or NotEnoughReplicasAfterAppendException). With acks=0 or acks=1, min.insync.replicas is ignored entirely because the producer is not asking for the all-replicas guarantee. So durability is a contract between two settings: the producer asks for acks=all, and the broker enforces how many replicas 'all' really means via min.insync.replicas.

go deeper

for a junior

Know the one-line definition: minimum in-sync replicas that must ack, and that it only kicks in with acks=all.

for a middle

Explain the gate vs. wait distinction and that acks=1/0 ignore the floor entirely.

for a senior

Articulate why acks=all without min.isr is effectively acks=1, and the durability-vs-availability tradeoff of refusing writes.

for a principal

Reason about cluster-wide defaults vs per-topic overrides, set durability SLOs, and teach the producer/broker contract to teams.

## The two settings Kafka stores each partition as a set of **replicas** — one **leader** and some **followers** — spread across brokers. The number of copies is the **replication factor (RF)**. Followers continuously fetch from the leader; those that are caught up (within `replica.lag.time.max.ms`, default 30s) form the **in-sync replica set (ISR)**. The leader is always in its own ISR. There are two distinct knobs that together define durability: - **`acks`** (producer-side): how many acknowledgements the producer waits for. `acks=0` = fire-and-forget, `acks=1` = leader only, `acks=all` (a.k.a. `acks=-1`) = wait for the full ISR. - **`min.insync.replicas`** (broker/topic-side): the minimum size the ISR must have for an `acks=all` write to be accepted. ## How they interact When a producer sends with **`acks=all`**, the leader appends the record and then waits until **every current ISR member** has replicated it before acknowledging. But before it even appends, the leader checks: *is the current ISR at least `min.insync.replicas`?* If not, it rejects the write immediately with **`NotEnoughReplicasException`**. If the ISR was large enough at append time but shrinks below the floor before all members confirm, the producer gets **`NotEnoughReplicasAfterAppendException`**. Crucially, **`min.insync.replicas` only has any effect with `acks=all`.** With `acks=0` or `acks=1`, the broker never consults it — the producer didn't ask for the strong guarantee, so the broker doesn't enforce a replica floor. This is the single most common point of confusion: setting `min.insync.replicas=2` does nothing unless your producers also use `acks=all`. ## Why both are needed `acks=all` alone is weaker than people think. 'All' means 'all replicas currently in the ISR' — and the ISR can shrink to just the leader. So `acks=all` with an ISR of size 1 is effectively `acks=1`: a single disk failure loses data. `min.insync.replicas` is what prevents that — it says 'all' must mean at least N copies, or refuse the write. Refusing the write (availability loss) is preferable to silently accepting a write that could be lost (durability loss). ## Edge cases - The floor is on the **ISR size**, not the replication factor. RF is the ceiling; ISR is the live count. - `min.insync.replicas` can be set at the broker level (`min.insync.replicas` in `server.properties`) and overridden per topic. - If `min.insync.replicas` >= RF, you have no fault tolerance for writes: losing a single replica drops you below the floor and blocks all `acks=all` producers.

  • If I set min.insync.replicas=2 but my producer uses acks=1, what durability do I actually get?
    Leader-only durability. min.insync.replicas is ignored with acks=1, so a write is acknowledged as soon as the leader persists it. If the leader fails before followers replicate, the write is lost. The floor has no effect.
  • Does acks=all wait for min.insync.replicas replicas or for the whole ISR?
    It waits for the whole current ISR to replicate the record. min.insync.replicas is only the minimum ISR size that must exist for the write to be accepted at all — it is a gate, not the number waited on.

saying these in an interview costs you the question

  • Saying min.insync.replicas applies regardless of acks level (it only matters with acks=all).
  • Claiming acks=all waits for all replicas including out-of-sync ones (it waits for the ISR only).
  • Confusing replication factor with min.insync.replicas — RF is the number of copies, min.isr is the live floor.
  • Thinking acks=all alone guarantees N copies (without min.insync.replicas the ISR can shrink to 1).

context

open as a page

Walk through what happens when the ISR shrinks below min.insync.replicas while producers are writing with acks=all.

level: middleimportance: must knowfreq 60%

basics

~10 s

The leader rejects new acks=all writes with NotEnoughReplicasException, so producers fail and retry. The partition becomes read-still-available but write-blocked until enough followers rejoin the ISR.

open as a page

Why is RF=3 with min.insync.replicas=2 the standard durable configuration, rather than RF=3/min.isr=3 or RF=2/min.isr=2?

level: seniorimportance: must knowfreq 65%

basics

~20 s

RF=3/min.isr=2 lets you survive one broker failure while still accepting writes and keeping two durable copies. RF=3/min.isr=3 blocks writes on any single failure; RF=2/min.isr=2 blocks writes on any single failure and has no spare copy.

open as a page

Where is min.insync.replicas configured, and how do you set up the full durability contract for a topic in practice?

level: middleimportance: should knowfreq 45%

basics

~10 s

min.insync.replicas is a broker default that can be overridden per topic. The full contract needs three parts: replication factor at topic creation, min.insync.replicas as a topic config, and acks=all on the producer.

open as a page

A team reports intermittent producer failures during routine broker maintenance. Their topic is RF=3, min.insync.replicas=3, acks=all. What is wrong and how would you reason about the fix?

level: seniorimportance: should knowfreq 40%

basics

~20 s

With min.insync.replicas equal to RF, taking any one broker down for maintenance drops the ISR from 3 to 2, below the floor of 3, so all acks=all writes fail. Lowering min.insync.replicas to 2 fixes it while keeping dual-copy durability.

open as a page