how to send batched data with Spring Kafka producer
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
With Spring Kafka, “send batched data” can mean two different things. You might want Kafka to batch many individual records efficiently on the wire, or you might want your application to send one message whose payload is itself a list of items. Those are related ideas, but they are configured differently.
Kafka Producer Batching
Kafka producers already batch records internally. In normal code, you still call send() once per record, and the Kafka client groups records together before sending them to the broker.
The main producer settings are:
- '
batch.size' - '
linger.ms' - '
buffer.memory'
In Spring Boot, you can configure them in application.yml:
Then send records normally:
This is the standard answer when you want better throughput without changing the payload structure.
What linger.ms Really Does
linger.ms tells the producer to wait briefly for more records before sending a batch. A small delay can improve throughput because more records fit into the same request.
That creates a tradeoff:
- larger linger usually improves batching
- larger linger can add latency
If your application is throughput-oriented, a small positive linger.ms is often helpful. If it is latency-sensitive, keep it lower.
Sending a List as One Kafka Message
Sometimes the requirement is different: you want to collect many domain objects and publish them as one logical message. In that case, you are not relying on Kafka’s producer batching alone. You are building your own batch payload.
For example, with JSON:
The consumer then reads a list payload, not many separate Kafka records.
Choosing Between the Two Approaches
Use Kafka’s built-in batching when:
- each event should stay independent
- consumers should process one record at a time
- you want better producer throughput transparently
Use an application-level batch payload when:
- the consumer expects one grouped unit of work
- the list must be handled atomically at the application level
- you want explicit batch semantics in the message contract
These choices affect downstream consumers, retries, and error handling, so they should be made deliberately.
Spring Configuration Example
If you want JSON payloads for list-based messages, configure a serializer that matches the value type.
This setup lets you publish structured batch payloads safely.
Common Pitfalls
One common mistake is assuming KafkaTemplate.send() must receive a list in order for Kafka batching to occur. It does not. Kafka batches ordinary individual sends internally.
Another issue is raising batch.size and linger.ms blindly without measuring throughput and latency. Bigger is not automatically better.
A third problem is using application-level list payloads when consumers actually need item-level retry or partitioning. A single bad item can then poison a whole batch message.
Summary
- Kafka producer batching already happens when you send records one by one.
- Tune
batch.sizeandlinger.mswhen the goal is throughput. - Sending a list payload is a different design choice from transport-level batching.
- Choose application-level batches only when grouped payload semantics are really required.
- Match serializers and consumer expectations to the batch strategy you choose.

