How to write Kafka consumers - single threaded vs multi threaded
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Kafka consumer design is mostly a tradeoff between simplicity and throughput. A single-threaded consumer is easier to reason about because polling, processing, and committing offsets happen in one place, while a multi-threaded design can increase throughput but requires deliberate control of partition ownership, ordering, and offset commits.
The Safe Baseline: One Consumer Per Thread
The Kafka Java KafkaConsumer is not thread-safe. That fact drives the design.
The simplest correct model is one thread, one consumer instance, polling records and processing them sequentially.
This is easy to debug and preserves per-partition ordering naturally. It is a good fit when processing is lightweight or when correctness matters more than raw throughput.
When Multi-Threading Helps
Multi-threading becomes attractive when per-record processing is expensive and the polling thread cannot keep up. But the consumer itself should still generally stay confined to one thread. The common pattern is:
- One polling thread owns the consumer.
- Records are handed off to worker threads.
- Offset commits happen only after worker completion is tracked safely.
That separation matters because calling consumer methods from arbitrary worker threads is a common mistake.
A Worker-Pool Pattern
A simplified architecture looks like this:
The key idea is to keep partition ordering intact by submitting work per partition rather than shuffling all records across threads arbitrarily.
Offset Commit Strategy Is the Real Complexity
The hardest part of multi-threaded consumption is not creating threads. It is deciding when an offset is safe to commit.
If you commit too early, a crash can lose unprocessed records. If you commit too late, you increase duplicate processing after restart. A correct design usually tracks the highest fully processed offset per partition and commits only those safe positions.
This is why many teams stay single-threaded longer than they expected. The throughput gain is real, but so is the coordination cost.
Partition Count Still Limits Parallelism
No matter how many worker threads you create, a consumer group cannot process more partitions in parallel than actually exist. If a topic has three partitions, spawning twenty consumer threads does not create twenty independent streams of ordered work.
So before building a complicated multi-threaded consumer, check whether the topic partition count is already the real throughput limit.
When to Scale Out Instead of Threading Up
A lot of Kafka consumer code becomes complicated because teams try to force more concurrency into one process before considering consumer-group scaling. Sometimes the simpler answer is to run more consumer instances and let Kafka distribute partitions naturally. That keeps ordering and offset management closer to the platform model instead of re-implementing concurrency control inside one application.
Common Pitfalls
- Sharing one
KafkaConsumerinstance across multiple threads even though it is not thread-safe. - Parallelizing records from the same partition in a way that breaks ordering guarantees.
- Committing offsets before worker threads have actually finished processing.
- Adding many worker threads when the topic has too few partitions to benefit.
- Choosing a complex multi-threaded design before measuring whether a simpler consumer is actually too slow.
Summary
- Start with a single-threaded consumer unless throughput measurements prove it is insufficient.
- The consumer instance itself should usually stay confined to one polling thread.
- Multi-threaded designs hand work to worker threads but keep offset management explicit.
- Preserve per-partition ordering when parallelizing processing.
- Partition count and commit strategy matter as much as thread count.
Related reading
- How to write Kafka Producer in Scala
- How to write spark streaming DF to Kafka topic
- How to write streaming dataset to Kafka?
- How to write to Kafka from Python logging module?
- How ZooKeeper guarantees Single System Image?
- I am trying to run kafka on windoes 10 but erros shows Error Could not find or load main class Files\kafka\libs\activation-1.1.1.jar;C\Program
- I am using Python3 and I want to use RabbitMQ
- I cannot start rabbitmq on my mac

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.