Consumer Prefetch
Consumer prefetch controls how many messages a broker may deliver to a consumer before that consumer has acknowledged earlier messages. It is a backpressure mechanism that trades throughput and concurrency against memory usage, fairness, and message distribution.
A consumer normally receives messages faster than it can process them at some points. Prefetch places a limit on the number of unacknowledged messages that can be outstanding for a consumer, preventing the broker from continuously pushing work into an already-busy application.
For example, with a prefetch value of `10`, a consumer can have up to roughly ten deliveries outstanding before additional deliveries are withheld, depending on the messaging system's exact semantics. As acknowledgements arrive, capacity becomes available and more messages can be delivered.
A smaller prefetch value generally provides stronger backpressure and can improve fairness when consumers have different processing speeds. A larger value can increase throughput by keeping the consumer supplied with work, but it can also increase memory usage, processing skew, and the amount of work tied up in one consumer.
The exact meaning of prefetch is broker-specific. In RabbitMQ, for example, QoS settings can constrain the number of unacknowledged deliveries, and the effective behavior can depend on whether limits are applied per consumer or through broader channel-level mechanisms. Interview answers should therefore distinguish the general idea from the semantics of the particular broker being used.
Key points
- Limits outstanding message deliveries to provide consumer-side backpressure.
- Higher prefetch can improve throughput but may increase memory use and uneven work distribution.
- Lower prefetch generally improves fairness and limits in-flight work.
- The exact scope and behavior of a prefetch setting depend on the messaging system.
- Prefetch is especially important when message processing is slow, variable, or resource-intensive.
Interview questions
What is consumer prefetch and why is it useful?
Consumer prefetch limits how many messages can be delivered to a consumer before earlier messages are acknowledged. It prevents a fast broker from overwhelming a slower consumer with unbounded in-flight work. This provides backpressure and can reduce memory pressure. The right value depends on processing cost, concurrency, and the broker's delivery semantics.
What are the trade-offs of increasing consumer prefetch?
Increasing prefetch can keep consumers supplied with work and reduce idle time, which may improve throughput. However, more messages can remain unacknowledged and resident in consumer-side memory. A high value can also make distribution less fair because one consumer may receive many messages before another gets work. The best setting therefore depends on message size, processing time, concurrency, and broker behavior.
How does prefetch interact with acknowledgements?
With acknowledgement-based processing, delivered but unacknowledged messages count toward the outstanding work allowed by the prefetch limit. Once acknowledgements are received, capacity becomes available for additional deliveries. This creates a feedback loop between processing completion and new message delivery. If acknowledgements are delayed, the consumer can remain at its prefetch limit even when it has already processed some work.
How would you tune prefetch for a Java service processing expensive messages?
I would start with a conservative value based on the service's actual processing concurrency and resource limits, then measure throughput, latency, memory usage, and consumer utilization. Expensive or large messages generally argue for avoiding a very large in-flight backlog. I would also consider processing-time variability and whether fair distribution across consumers matters. Tuning should be validated under representative load rather than choosing a value solely from a rule of thumb.
Why might a very high prefetch cause uneven work distribution among consumers?
A broker may assign a large batch of messages to one consumer before that consumer has finished processing them. Those messages can remain unavailable to other consumers while they are outstanding, even if another consumer becomes idle. This effect is particularly noticeable when processing times vary significantly. Reducing prefetch can allow the broker to distribute work more incrementally, although the exact behavior depends on the broker's dispatch and acknowledgement semantics.