[[rabbit-receiving-batch]] = Receiving Batched Messages With the RabbitMQ binder, there are two types of batches handled by consumer bindings: [[batches-created-by-producers]] == Batches Created by Producers Normally, if a producer binding has `batch-enabled=true` (see xref:rabbit/rabbit_overview/prod-props.adoc[Rabbit Producer Properties]), or a message is created by a `BatchingRabbitTemplate`, elements of the batch are returned as individual calls to the listener method. Starting with version 3.0, any such batch can be presented as a `List` to the listener method if `spring.cloud.stream.bindings..consumer.batch-mode` is set to `true`. [[consumer-side-batching]] == Consumer-side Batching Starting with version 3.1, the consumer can be configured to assemble multiple inbound messages into a batch which is presented to the application as a `List` of converted payloads. The following simple application demonstrates how to use this technique: [source, properties] ---- spring.cloud.stream.bindings.input-in-0.group=someGroup spring.cloud.stream.bindings.input-in-0.consumer.batch-mode=true spring.cloud.stream.rabbit.bindings.input-in-0.consumer.enable-batching=true spring.cloud.stream.rabbit.bindings.input-in-0.consumer.batch-size=10 spring.cloud.stream.rabbit.bindings.input-in-0.consumer.receive-timeout=200 ---- [source, java] ---- @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean Consumer> input() { return list -> { System.out.println("Received " + list.size()); list.forEach(thing -> { System.out.println(thing); // ... }); }; } @Bean public ApplicationRunner runner(RabbitTemplate template) { return args -> { template.convertAndSend("input-in-0.someGroup", "{\"field\":\"value1\"}"); template.convertAndSend("input-in-0.someGroup", "{\"field\":\"value2\"}"); }; } public static class Thing { private String field; public Thing() { } public Thing(String field) { this.field = field; } public String getField() { return this.field; } public void setField(String field) { this.field = field; } @Override public String toString() { return "Thing [field=" + this.field + "]"; } } } ---- [source] ---- Received 2 Thing [field=value1] Thing [field=value2] ---- The number of messages in a batch is specified by the `batch-size` and `receive-timeout` properties; if the `receive-timeout` elapses with no new messages, a "short" batch is delivered. IMPORTANT: Consumer-side batching is only supported with `container-type=simple` (the default). If you wish to examine headers of consumer-side batched messages, you should consume `Message>`; the headers are a `List>` in a header `AmqpInboundChannelAdapter.CONSOLIDATED_HEADERS`, with the headers for each payload element in the corresponding index. Again, here is a simple example: [source, java] ---- @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean Consumer>> input() { return msg -> { List things = msg.getPayload(); System.out.println("Received " + things.size()); @SuppressWarnings("unchecked") List> headers = (List>) msg.getHeaders().get(AmqpInboundChannelAdapter.CONSOLIDATED_HEADERS); for (int i = 0; i < things.size(); i++) { System.out.println(things.get(i) + " myHeader=" + headers.get(i).get("myHeader")); // ... } }; } @Bean public ApplicationRunner runner(RabbitTemplate template) { return args -> { template.convertAndSend("input-in-0.someGroup", "{\"field\":\"value1\"}", msg -> { msg.getMessageProperties().setHeader("myHeader", "headerValue1"); return msg; }); template.convertAndSend("input-in-0.someGroup", "{\"field\":\"value2\"}", msg -> { msg.getMessageProperties().setHeader("myHeader", "headerValue2"); return msg; }); }; } public static class Thing { private String field; public Thing() { } public Thing(String field) { this.field = field; } public String getfield() { return this.field; } public void setfield(String field) { this.field = field; } @Override public String toString() { return "Thing [field=" + this.field + "]"; } } } ---- [source] ---- Received 2 Thing [field=value1] myHeader=headerValue1 Thing [field=value2] myHeader=headerValue2 ----