Knowledge Guide
HomeSystem DesignKafka

hard Kafka Consumer-Group Rebalancing

A rebalance is the coordinator re-dealing partitions whenever the group's membership changes

Every partition of a topic must be owned by exactly one consumer within a consumer group at a time. The group coordinator (a broker) tracks membership through heartbeats each consumer sends on heartbeat.interval.ms; if a member's heartbeats stop arriving for longer than session.timeout.ms, or a member explicitly joins or leaves, the coordinator triggers a rebalance — it recomputes which consumer owns which partitions using the group's configured assignor, and hands out the new assignment. The part that actually matters for your throughput is how much processing has to pause while that recomputation happens, and that is entirely determined by which rebalance protocol the group uses.

Group coordinator receiving heartbeats from consumers C1 and C2 while C3 crashes and stops sending heartbeats; once session.timeout.ms elapses the coordinator sends a rebalance signal to the surviving members
Group coordinator receiving heartbeats from consumers C1 and C2 while C3 crashes and stops sending heartbeats; once session.timeout.ms elapses the coordinator sends a rebalance signal to the surviving members

Both protocols answer the same question — "who owns which partition now?" — but eager answers it by pausing everyone and cooperative answers it by pausing only the partitions that changed hands.

Traced: C3 joins a 2-consumer, 6-partition group

Topic has 6 partitions (P0–P5); the group starts with C1 owning {P0,P1,P2} and C2 owning {P3,P4,P5}. A new instance, C3, starts up and sends a JoinGroup request.

What happensWhat keeps processing during the transition
EagerCoordinator detects the new member → sends a rebalance signal → C1 and C2 both revoke all six partitions → all three rejoin → coordinator assigns C1{P0,P1}, C2{P2,P3}, C3{P4,P5} → every consumer resumes together.Nothing. Even P0/P1, which end up back on C1, are paused for the full round trip.
CooperativeCoordinator computes the same kind of target, but a sticky assignor tries to keep existing ownership: C1{P0,P1,P2} unchanged, C2{P3,P4}, C3{P5}. Round 1: only C2 revokes P5. Round 2: C3 is assigned P5.P0–P4 keep flowing the entire time; only P5 has a brief gap.
Side-by-side comparison: eager rebalance revokes all six partitions across the group when C3 joins, stalling everything, while cooperative rebalance revokes only the one partition that must move (P5), leaving P0 through P4 processing uninterrupted
Side-by-side comparison: eager rebalance revokes all six partitions across the group when C3 joins, stalling everything, while cooperative rebalance revokes only the one partition that must move (P5), leaving P0 through P4 processing uninterrupted

Rebalance storms & static membership

A rebalance storm is repeated, cascading rebalances that keep the group from ever settling — usually caused by a flapping member: a consumer whose processing occasionally exceeds max.poll.interval.ms (a separate liveness check from the heartbeat thread, introduced so a slow-but-alive consumer doesn't block the group forever) gets treated as dead and kicked out, rejoins, gets reassigned partitions, and repeats. A session.timeout.ms set too aggressively low has the same effect: normal GC pauses or brief network jitter look like a crash, triggering a rebalance that didn't need to happen. Kafka's own default was raised from 10s to 45s (KIP-735) specifically because 10s produced too many false-positive rebalances in production.

Static membership (group.instance.id set to a stable, per-instance value) fixes a different failure mode: routine rolling restarts. Without it, every restarted consumer is a brand-new dynamic member, so a rolling deploy of N consumers triggers N rebalances. With a static ID, the coordinator recognizes the returning process as the same member reconnecting within its session window and simply restores its old assignment — no rebalance fires at all for a planned bounce.

Pitfalls

When to use eager vs. cooperative — and the trade-off

Session / heartbeat tuning: fast failure detection vs. false rebalances

Lowering session.timeout.ms detects a genuinely crashed consumer sooner — its partitions sit un-consumed for less time, which matters when consumer lag has a latency SLA. But push it too low and ordinary jitter (a GC pause, a slow disk flush, a momentary network blip) crosses the threshold and fires an unnecessary rebalance, which now stalls the whole group under eager, or at least the moving partitions under cooperative — for a failure that wasn't real. Raising the timeout trades slower failover for fewer false positives. There is no value that is simply "correct"; it is set against how tolerant the workload is of (a) a slow real failover vs (b) an occasional unnecessary pause, which is exactly why Kafka's own shipped default moved from 10s to 45s once the false-positive cost became clear in practice.

Takeaways


Sources: Apache Kafka documentation — consumer group protocol, session.timeout.ms/heartbeat.interval.ms/max.poll.interval.ms, ConsumerPartitionAssignor, and static membership (group.instance.id, KIP-345); KIP-429 (Incremental Cooperative Rebalancing); KIP-735 (session timeout default change); Neha Narkhede/Gwen Shapira/Todd Palino, Kafka: The Definitive Guide, ch. 4 (Consumers). Re-authored for this guide; both diagrams hand-authored as SVG. See also: Kafka Internals (partitions & consumer groups), Kafka Durability Under Broker Failure.

🤖 Don't fully get this? Learn it with Claude

Stuck on Kafka Consumer-Group Rebalancing? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Kafka Consumer-Group Rebalancing** (System Design) and want to truly understand it. Explain Kafka Consumer-Group Rebalancing 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.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Kafka Consumer-Group Rebalancing** 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.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Kafka Consumer-Group Rebalancing** 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.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Kafka Consumer-Group Rebalancing** 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.

📝 My notes