skip to content

Compare RangeAssignor, RoundRobinAssignor, and StickyAssignor. When would you pick each?

level: middleimportance: must knowfreq 70%

answer

  1. Range = per-topic contiguous, joins, front-loaded skew
  2. RoundRobin = all partitions flattened, even, reshuffles
  3. Sticky = even + minimize movement
  4. Sticky still revokes everything (eager)
  5. leader picks first strategy ALL members support

basics

~10 s

RangeAssignor assigns contiguous partition ranges per topic (can imbalance with multiple topics). RoundRobinAssignor spreads all partitions evenly across consumers. StickyAssignor balances evenly while trying to keep previous assignments stable across rebalances.

solid answer

~50 s

These are values of `partition.assignment.strategy`. RangeAssignor (the historic default) works per topic: it sorts partitions and consumers, then hands each consumer a contiguous range — so with multiple topics the same low-index consumers tend to get extra partitions, causing skew, but it co-locates same-index partitions across topics (handy for joins). RoundRobinAssignor treats all subscribed partitions across all topics as one list and deals them out round-robin, giving the most even spread but reshuffling everything on each rebalance. StickyAssignor also aims for an even spread but adds a stickiness goal: it minimizes partition movement between rebalances, so consumers tend to keep what they had, reducing state/cache churn. Pick Range for co-partitioned joins, RoundRobin for even load across many topics, and Sticky when you want even load AND low movement — though in modern Kafka you'd usually choose CooperativeStickyAssignor instead.

go deeper

for a junior

Know the names and one-line behavior: Range = contiguous, RoundRobin = even spread, Sticky = even + stable.

for a middle

Explain Range's multi-topic skew, RoundRobin's reshuffle cost, and that Sticky minimizes movement but is still eager.

for a senior

Discuss co-partitioning trade-offs, migration between strategies, and why stickiness matters for stateful consumers.

for a principal

Advise on assignor choice across a fleet given stateful processing, join requirements, and operational churn; reason about custom assignors.

## The config `partition.assignment.strategy` is a consumer config holding an ordered list of assignor class names. The group leader picks the *first* strategy supported by *all* members. Built-in options: ## RangeAssignor (`org.apache.kafka.clients.consumer.RangeAssignor`) Works **per topic, independently**. For each topic it sorts partitions numerically and consumers lexicographically, divides `numPartitions / numConsumers`, and gives each consumer a **contiguous range**. The first consumers get the remainder. Example: topic with 7 partitions, 3 consumers C0,C1,C2 -> C0 gets p0-2, C1 gets p3-4, C2 gets p5-6 (front-loaded). - **Pro:** for two co-partitioned topics, partition *i* of both topics lands on the same consumer — useful for stream-stream joins. - **Con:** with many topics, the front consumers (C0...) accumulate the leftover partition from *every* topic -> systematic imbalance. ## RoundRobinAssignor (`...RoundRobinAssignor`) Flattens **all partitions of all subscribed topics** into one list, sorts, and deals them round-robin across all consumers. - **Pro:** maximally even when all consumers subscribe to the same topics; differs by at most one partition. - **Con:** uneven subscriptions break it; and every rebalance can reshuffle nearly everything (no stickiness). ## StickyAssignor (`...StickyAssignor`) Two goals, in priority order: (1) assignment as **balanced** as possible, (2) when reassigning, **preserve as many existing owner->partition mappings** as possible. On the first assignment it behaves like round-robin; on later ones it keeps consumers' partitions where balance allows. - **Pro:** less movement -> less reprocessing, less local-state/cache rebuild, fewer offset re-seeks. - **Con:** it is still an **eager** assignor — every member still revokes ALL partitions at the start of the rebalance (stickiness only affects the *new* assignment, not the revoke). To also avoid the revoke-everything step you need CooperativeStickyAssignor. ## Choosing | Need | Pick | |------|------| | Co-partitioned joins (same index together) | Range | | Evenest spread across many uniform topics | RoundRobin | | Even spread + minimal churn | Sticky (or, preferably, CooperativeSticky) | ## Edge cases - Mixed strategies across members: the leader uses the first one **all** members list. Rolling a new strategy requires supporting both old and new simultaneously during the migration. - All these classic assignors (except CooperativeSticky) use the **eager** rebalance protocol. - Custom assignors are possible by implementing `ConsumerPartitionAssignor`.

  • Why can RangeAssignor cause imbalance when a group subscribes to many topics?
    Because it runs per topic independently and front-loads the remainder onto the lexicographically-first consumers. With N topics, those same early consumers get the extra partition for each topic, so they accumulate N extra partitions while later consumers get none of the leftovers.
  • If StickyAssignor minimizes movement, why might you still see a stop-the-world pause?
    Because StickyAssignor uses the eager protocol: every member revokes ALL of its partitions and stops consuming before the new assignment is sent. Stickiness only reduces which partitions end up *moving* in the final assignment; it does not avoid the revoke-all step. CooperativeStickyAssignor is what removes that pause.

saying these in an interview costs you the question

  • Claiming StickyAssignor avoids stop-the-world (it doesn't — only CooperativeSticky does).
  • Saying RoundRobin and Range produce the same result regardless of topic count.
  • Forgetting that the leader picks the first strategy supported by ALL members, not just its own preference.
  • Describing Range as operating globally across topics — it is per-topic.

context