Prefetch Count & QoS
IntermediatebasicQos limits the number of unacknowledged messages a consumer can hold; low prefetch ensures even work distribution and prevents a slow consumer from monopolising the queue.
Overview
By default RabbitMQ pushes messages to a consumer as fast as the network allows. Without a prefetch limit, a fast consumer could grab hundreds of messages while a slow one sits idle — defeating the purpose of a worker-queue pattern. `basic.qos` (Quality of Service) sets the maximum number of unacknowledged messages the broker will deliver to a single channel before waiting for an ack. Setting `prefetchCount = 1` guarantees round-robin-like fairness: a consumer only gets a new message once it has acknowledged the previous one. Higher prefetch values improve throughput but reduce fairness. In Spring AMQP the equivalent is `SimpleMessageListenerContainer.setPrefetchCount()`.
How basicQos Works
The broker tracks a per-channel "unacked" counter. Each delivered message increments it; each ack decrements it. When the counter reaches `prefetchCount`, the broker stops delivering on that channel until an ack arrives. Setting `global=false` (the default) applies the limit per consumer on the channel; `global=true` applies it to the whole channel. Most use cases want per-consumer limits.
// AMQP Java client
Channel channel = connection.createChannel();
// Allow at most 5 unacknowledged messages per consumer
channel.basicQos(5 /*, global= false (default) */);
channel.basicConsume("orders", false, (tag, delivery) -> {
try {
process(delivery.getBody());
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
} catch (Exception e) {
// requeue=false → routed to DLX if configured
channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, false);
}
}, tag -> {});Spring AMQP Prefetch Configuration
Spring Boot's auto-configured `SimpleRabbitListenerContainerFactory` exposes `spring.rabbitmq.listener.simple.prefetch` in application.properties. For fine-grained control, customise the factory bean directly. The default prefetch in Spring AMQP is 250 — great for throughput but can cause imbalance with slow tasks; lower it for CPU-intensive or long-running consumers.
# application.properties
spring.rabbitmq.listener.simple.prefetch=1 # fair dispatch
spring.rabbitmq.listener.simple.acknowledge-mode=manual
# --- OR via Java config ---
@Bean
SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
ConnectionFactory cf) {
var factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(cf);
factory.setPrefetchCount(5);
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
return factory;
}Choosing the Right Prefetch Value
There is no single "right" prefetch. For **long tasks** (> 1 s each), use prefetch=1 for fairness. For **short tasks** (< 10 ms), use prefetch=10–100 to keep consumers busy without extra round trips. For **batch consumers** set prefetch equal to the batch size. Monitor consumer utilisation with `rabbitmq_queue_consumers` and `rabbitmq_queue_messages_unacknowledged` Prometheus metrics and tune accordingly.
# Prometheus alert — consumer sitting idle because prefetch too low
- alert: RabbitConsumerStarved
expr: |
rabbitmq_queue_messages_ready > 100
and rabbitmq_queue_consumers > 0
and rabbitmq_queue_messages_unacknowledged == 0
for: 2m
annotations:
summary: "Consumers idle but queue has {{ $value }} messages — raise prefetch"Key Points to Remember
- 1basicQos(n) stops the broker delivering more than n unacked messages to a consumer
- 2prefetch=1 gives the fairest distribution; higher values improve throughput
- 3Spring AMQP default prefetch is 250 — lower it for slow/CPU-heavy tasks
- 4global=false (default) applies the limit per consumer; global=true per channel
- 5Always combine manual ack with a sensible prefetch — auto-ack ignores QoS
- 6Monitor unacked message counts in Prometheus to find the optimal value
Interview Questions
Sign in to ask AriaWhat happens if you set prefetchCount to 0 in RabbitMQ?
Explain the difference between global=true and global=false in basicQos.
Why does the default Spring AMQP prefetch of 250 cause problems with slow consumers?
How would you choose an optimal prefetch count for a queue processing image thumbnails?
Does prefetch affect consumers using auto-ack mode?
Ask Aria about Prefetch Count & QoS
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.