Skip to content
About
Main content

Choosing N

How many partitions should a stream have, and why is changing the number later a project?

N is the number that sets your parallelism ceiling and your ordering scope at the same time. It deserves its own section because it is the one decision in this article that you make once.

Too low: parallelism is capped below what you need. Adding does nothing. A single hot cannot be fixed.

Too high:

  • more files and smaller batches downstream (the small-files problem);
  • more metadata;
  • more per-partition overhead (memory, file handles, replication traffic);
  • longer rebalances and longer leader elections (a rebalance reassigns partitions among consumers; a leader election picks the that accepts writes for a partition);
  • more coordination on failure;
  • and more variance: with many partitions and moderate key , gets worse, not better.

Heuristics

  • N ≥ target_throughput / per_consumer_throughput, then multiply by 2–3 for headroom.
  • N ≥ max_consumers_you_will_ever_want. This is the ceiling, and it is to raise.
  • Choose N so that the number of distinct keys per partition is comfortably above 1. Otherwise partition skew dominates.
  • Prefer a (12, 24, 60, 120, 360), meaning a number with many divisors. If you ever reassign partitions to consumers, a composite N divides evenly among many consumer counts. It is a small thing that occasionally saves you.
  • Consider at the start and running several partitions per consumer. Consumers can scale up later without a repartition. It costs some per-partition overhead now, and buys the one change you cannot otherwise make.

Consumer groups and rebalancing

N caps how many consumers in a group can work, because each partition is read by one member of the group at a time. Which member reads which partition is decided by the group itself, and it is decided again whenever a member joins, leaves, or is declared dead. That redistribution is a rebalance, and it costs three things:

  • A pause. Partitions that change owner are not consumed until the new owner has them.
  • Repeats. A partition moves with the its old owner last committed. Everything the old owner processed after that commit is processed again by the new owner, so a rebalance is a source of duplicates like a crash.
  • Cold state. A stateful consumer must rebuild or fetch the state of each partition it receives before it can continue.

How much of the group pays depends on the protocol:

ProtocolWhat happens on a changeWho pauses
Eager (the original, "stop the world")every member gives up all its partitions, the group re-forms, and every partition is assigned againthe whole group, for every change
Cooperative (incremental, Kafka's CooperativeStickyAssignor)only the partitions that must move are revoked, over two short rounds; the rest keep runningonly the members that lose or gain a partition
Static membership (group.instance.id)a member that restarts within the session gets its partitions back with no rebalance at allnobody, for a rolling restart

Two habits keep the repeats small. Commit the offsets of work already done when partitions are revoked (Kafka calls the consumer back in onPartitionsRevoked), so the new owner starts where the old one stopped. And keep the short enough that what a rebalance repeats is something the sink can absorb. A rebalance that is triggered by a slow member rather than a dead one feeds itself: see the in Connection pooling, keep-alive and heartbeats.

Changing N later

For a log, increasing the partition count breaks the key-to-partition mapping, so per-key order is broken across the change. For stateful consumers, the state must be redistributed. The clean path is usually a new topic with the new partition count, then (write to both topics) or , then cut over, not an in-place change. Budget for it. It is a project, not a configuration edit.


What to carry out of this article

Balance and locality are opposed, and you must pick. Everything else here is a technique for making the loss tolerable.

Your partition key is your ordering scope, your state locality, your parallelism ceiling and your skew profile. That is one decision with four consequences. It is the least reversible choice in your pipeline, so spend your time accordingly.

A DLQ is not a safety net. It is a trade of completeness and order for availability. If nobody monitors it, it is data loss with a dashboard.

Multiplexing relocates head-of-line blocking. It does not eliminate it. Always ask what the layer below guarantees.