RabbitMQ Consumer Prefetch & QoS Tuning Prompt
Tune consumer prefetch (basic.qos) so work is spread evenly across consumers, throughput is high, and no single consumer hoards or starves while others sit idle.
- Target user
- Backend and platform engineers tuning RabbitMQ consumers
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior platform engineer who has tuned RabbitMQ consumer prefetch across high-throughput and slow-task workloads. Help me set the right QoS for mine. I will provide: - The workload shape: messages per second, per-message processing time, variance (fast vs slow tasks) [DESCRIBE] - Consumer count and concurrency model (threads/processes per consumer) [DESCRIBE] - Current settings and symptoms: `rabbitmqctl list_queues name consumers consumer_utilisation messages_unacknowledged` [PASTE OUTPUT] - Whether prefetch is set per-channel or global, and the current value [DESCRIBE] Your job: 1. **Diagnose the current state** — low `consumer_utilisation` with idle consumers usually means prefetch is too low (consumers wait for the round-trip); uneven work and a big `messages_unacknowledged` pile on one consumer usually means prefetch is too high (one consumer hoards). 2. **Recommend a prefetch value** — reason from message processing time and round-trip latency, not a magic number. Explain why short, uniform tasks tolerate higher prefetch for throughput while long or highly variable tasks need low prefetch (often 1) for fair distribution. 3. **Per-channel vs global QoS** — clarify how prefetch applies (per-consumer by default), what global QoS changes, and the impact of multiple consumers sharing a channel. 4. **Account for acks** — prefetch only limits UNACKED messages, so consumers must ack promptly; a consumer that delays acks effectively lowers its own throughput and holds its prefetch budget. 5. **Validate the change** — what to watch after tuning: utilisation toward 1.0, even unacked distribution, total throughput, and no growth in `messages_ready`. Output as: (a) the diagnosis with the metric that proves it, (b) a recommended prefetch value with the reasoning, (c) per-channel vs global guidance, (d) the metrics to confirm the change worked. Validate prefetch changes on a staging broker or a canary consumer before rolling fleet-wide. A too-high prefetch on slow tasks can leave messages unacked for a long time, so watch `messages_unacknowledged` and avoid changes that risk stranding work if a consumer dies mid-batch.
Why this prompt works
Prefetch is the single most misunderstood RabbitMQ consumer setting. Set it too low and consumers spend their time idle waiting for the next message round-trip, tanking throughput. Set it too high and one greedy consumer grabs a huge batch while its peers starve, destroying the fair work distribution that competing consumers are supposed to give you. The prompt diagnoses which failure you’re in using consumer_utilisation and the distribution of messages_unacknowledged, then reasons toward a value from actual processing time and round-trip latency instead of copying a number off a blog.
It anchors on the core fact that prefetch only limits unacknowledged messages, which makes consumer ack behavior part of the tuning problem. A consumer that holds messages without acking is silently capping its own throughput and its prefetch budget — a detail that explains a lot of “we raised prefetch and nothing improved” confusion. The prompt also separates per-channel from global QoS, which trip people up when consumers share a channel.
The guardrails reflect the real risk of a high prefetch: a consumer that dies mid-batch causes every unacked message it held to be redelivered. For long-running or non-idempotent work, that blast radius matters, so the prompt keeps prefetch modest there and pushes canary validation before a fleet-wide change.