CodePark/ questions / RabbitMQ: acks, prefetch & dead-lettering
START PRACTICINGPRACTICE
Backend question · Message queues & streaming › RabbitMQ: acks, prefetch & dead-lettering

What is the difference between automatic and manual acknowledgements in RabbitMQ, and what happens to unacked messages when a consumer crashes?

With automatic acks, a message is lost if the consumer crashes. With manual acks, unacked messages go back to the queue and are delivered again.

An ack (acknowledgement) is the consumer telling the broker "I am done with this message". The broker is the RabbitMQ server.

With automatic acknowledgement (noAck: true in amqplib), the broker treats a message as delivered as soon as it sends it. If the consumer crashes in the middle of the work, the message is gone. This is at-most-once delivery: each message arrives once or not at all.

With manual acknowledgement, the consumer calls ack after it has finished the work. Until then, the message is unacked, and the broker still owns it. Suppose the consumer's channel or connection closes. Then the broker puts every unacked message back in the queue. It delivers them again with the redelivered flag set. This is at-least-once delivery: a message can arrive more than once. So the handler must cope with duplicates.

Manual acks also let you call nack or reject on a message. This either puts it back in the queue or sends it to a dead-letter exchange. Remember to ack on every code path. If you forget an ack, the message stays stuck as unacked until the consumer disconnects.

  • With auto-ack, the broker removes the message when it sends it, so a consumer crash loses it.
  • A manual ack after processing gives at-least-once delivery.
  • When the channel closes, unacked messages go back to the queue with the redelivered flag.
  • Use nack or reject to requeue a message or dead-letter it.
  • A forgotten ack leaves the message stuck as unacked.