Back to results for “Error Handling”
Node.js › Message Queues (RabbitMQ & Kafka)

What is the difference between message acknowledgment modes (auto-ack vs manual ack) in a message queue, and why does manual ack matter for reliability?

Intermediate

Answer

Auto-acknowledgment marks a message as successfully processed the instant it's delivered to a consumer, before any actual processing logic has even run -- if the consumer then crashes while processing, that message is permanently lost since the broker already considers it delivered. Manual acknowledgment defers this until the consumer explicitly confirms successful processing, so if a crash happens mid-processing, the broker detects the missing acknowledgment (typically via a connection loss) and redelivers the message to another consumer, providing genuine at-least-once delivery guarantees.
// Risky: auto-ack, message is 'confirmed received' before processing even starts
channel.consume('orders', processOrder, { noAck: true });

// Reliable: manual ack, only confirmed after processing genuinely succeeds
channel.consume('orders', async (msg) => {
  await processOrder(JSON.parse(msg.content.toString()));
  channel.ack(msg); // only now does the broker consider it handled
}, { noAck: false });
Real-world example A payment-processing consumer that used auto-ack for simplicity lost several in-flight payment confirmation messages during a deployment restart; switching to manual acknowledgment, only calling ack() after the payment was fully and successfully recorded, ensured any interrupted messages were automatically redelivered and retried instead of silently disappearing.

Common follow-ups: What's the tradeoff of manual acknowledgment in terms of the possibility of processing the same message twice (at-least-once rather than exactly-once)?;How does this relate back to the job idempotency concept discussed for background job queues?