Updated on 2023-05-06 GMT+08:00

Prefetch

Scenario

Prefetch limits the number of unacknowledged messages. Once a consumer has more unacknowledged messages than the prefetch limit, the server stops sending messages to the consumer, unless at least one message is acknowledged. Prefetch is essentially a flow control measure on consumers.

Consider the following factors when setting prefetch:

  • If the limit is too low, the performance may be affected, because RabbitMQ keeps waiting for the permission to send messages.
  • If the limit is too high, a large number of messages may be transmitted to a consumer, leaving other consumers idle. In addition, you also need to consider consumer configurations. When processing messages, consumers save all messages in the memory. A high prefetch limit may affect consumer performance and may even crash the consumer.

For details about prefetch, see Consumer Prefetch.

What Is a Proper Prefetch Limit?

  • If you have only one or a few consumers processing messages, it is recommended that you prefetch multiple messages at a time to keep the client busy. If your processing time and network status are stable, you can obtain an estimated prefetch value by dividing the total round-trip time by the processing time of each message on the client.
  • If you have a large number of consumers and the processing time is short, a low prefetch limit is recommended. However, if the limit is too low, consumers will be idle after they have processed a batch of messages but the next batch has not yet arrived. If the limit is too high, a single consumer may be busy while other consumers are idle.
  • If you have a large number of consumers and the processing time is long, set the prefetch value to 1 so that messages can be evenly distributed among all consumers.

If automatic message acknowledgment has been configured on the client, the prefetch value is invalid, and acknowledged messages are deleted from queues.

Setting the Prefetch Value

The following example shows how to set the prefetch value to 10 for a single consumer on a Java client.

ConnectionFactory factory = new ConnectionFactory();

Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

channel.basicQos(10, false);

QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume("my_queue", false, consumer);

On a Java client, the default value of global is false. Therefore, the preceding example can be simply written as channel.basicQos(10).

The values of global are described as follows.

Table 1 Description of global values

Value of global

Description

false

Applied separately to each new consumer on the channel.

true

Shared among all consumers on the channel.