Reliability — Cheat Sheet
RabbitMQ · 3 topics. Download the PDF or the Instagram carousel and share it.
Cheat Sheet · AiCanCode.org
Reliability
RabbitMQ3 topicsQuick revision reference
1
Publisher Confirms
Publisher confirms are an async acknowledgement from the broker that a message was routed and written; essential to know a message is not lost between producer and broker.
- ✓Without publisher confirms, basicPublish is fire-and-forget — messages can be silently lost on broker failure or network drop.
- ✓Confirm mode (channel.confirmSelect) assigns a delivery tag to each message; broker sends ack or nack asynchronously.
- ✓Async confirm listeners (addConfirmListener) are preferred over waitForConfirms() for production throughput.
- ✓Spring AMQP: set publisher-confirm-type=CORRELATED and ConfirmCallback + ReturnsCallback on RabbitTemplate.
- ✓Publisher confirms + durable queues + persistent messages = complete end-to-end message durability guarantee.
- ✓Channel transactions are ~250× slower than confirms — use confirms for throughput-sensitive production code.
Java — Publisher Confirms (AMQP Client)
Channel channel = connection.createChannel();
// Put channel in confirm mode — every publish gets a sequence number
channel.confirmSelect();
// Async confirm listener — fires on broker ack or nack
channel.addConfirmListener(
(deliveryTag, multiple) -> {
// ACK: broker persisted the message
log.info("Confirmed delivery tag {}", deliveryTag);
},
(deliveryTag, multiple) -> {
// NACK: broker could NOT persist — resend or alert
log.error("Broker nacked delivery tag {} — message lost!", deliveryTag);
retryPublish(deliveryTag);
}
);
// Publish a persistent message
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
.deliveryMode(2) // persistent
.build();
channel.basicPublish("orders", "order.created", props, messageBody);
// Synchronous wait — blocks until all pending confirms arrive (lower throughput)
boolean allConfirmed = channel.waitForConfirms(5000); // 5s timeout
if (!allConfirmed) {
throw new RuntimeException("Some messages not confirmed by broker");
}2
Consumer Acknowledgements (ack/nack)
basicAck signals successful processing; basicNack/basicReject requeues or discards the message. Unacknowledged messages are redelivered if the consumer disconnects.
- ✓Manual-ack (autoAck=false) is the safe default: messages are requeued if the consumer crashes before acking.
- ✓basicAck → processed successfully; basicNack(requeue=true) → retry; basicNack(requeue=false) → dead-letter or discard.
- ✓Never requeue=true for a message that always fails — it creates an infinite poison-message loop; route to DLQ instead.
- ✓Set prefetch (basicQos) together with manual ack for fair dispatch: each consumer only receives the next message after acking the previous one.
- ✓Auto-ack deletes the message on delivery — before processing — acceptable only for non-critical fire-and-forget scenarios.
- ✓In Spring AMQP, set acknowledge-mode: MANUAL and inject Channel into the @RabbitListener method to call ack/nack.
Java — AMQP Manual Ack
Channel channel = connection.createChannel();
// Set prefetch — limits unacked messages to 1 (fair dispatch)
channel.basicQos(1);
// Consume with manual ack (autoAck = false)
channel.basicConsume("order-queue", false, (consumerTag, delivery) -> {
long deliveryTag = delivery.getEnvelope().getDeliveryTag();
try {
Order order = deserialize(delivery.getBody());
orderService.process(order);
// SUCCESS — ack the message; broker removes it
channel.basicAck(deliveryTag, false);
} catch (TransientException e) {
// Transient failure — requeue for retry
channel.basicNack(deliveryTag, false, true);
} catch (PoisonMessageException e) {
// Permanent failure — do NOT requeue; routes to DLX if configured
channel.basicNack(deliveryTag, false, false);
}
}, consumerTag -> {});3
Prefetch Count & QoS
basicQos 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.
- ✓basicQos(n) stops the broker delivering more than n unacked messages to a consumer
- ✓prefetch=1 gives the fairest distribution; higher values improve throughput
- ✓Spring AMQP default prefetch is 250 — lower it for slow/CPU-heavy tasks
- ✓global=false (default) applies the limit per consumer; global=true per channel
- ✓Always combine manual ack with a sensible prefetch — auto-ack ignores QoS
- ✓Monitor unacked message counts in Prometheus to find the optimal value
Java — AMQP client basicQos
// 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 -> {});Learn this free with Aria, your AI tutor → AiCanCode.org/learn/rabbitmq