{"id":"b0aeafba-cfbc-420d-8d86-7aa115e992b7","task":"Publish messages to RabbitMQ reliably using publisher confirms and configure consumers with prefetch and a dead-letter exchange","domain":"rabbitmq","steps":["Enable publisher confirms on the channel by calling channel.confirmSelect() (AMQP confirm.select); after this, every published message is assigned a delivery tag and the broker sends a basic.ack or basic.nack confirming persistence to disk (if the queue and message are durable)","Publish messages with delivery_mode=2 (persistent) and ensure both the exchange and queue are declared as durable=True; messages to non-durable queues or exchanges will not survive a broker restart even with publisher confirms enabled","For consumers, set the channel prefetch count (basic.qos with prefetch_count) before starting consumption; a prefetch of 1 ensures a consumer only holds one unacknowledged message at a time (fair dispatch), while higher values improve throughput at the cost of uneven distribution","Acknowledge messages manually (basic.ack with the delivery tag) after successful processing; use basic.nack with requeue=False to reject a message without requeueing (sends it to the dead-letter exchange if configured)","Configure a dead-letter exchange (DLX) on the queue by setting the x-dead-letter-exchange argument at queue declaration time; bind a separate queue to the DLX to receive rejected or expired messages for inspection and reprocessing","Set x-message-ttl on the queue or per-message to expire unprocessed messages after a timeout; expired messages are routed to the DLX just like nacked messages"],"gotchas":["Publisher confirms are asynchronous — you can publish a batch and then wait for all confirms rather than confirm-per-message; not waiting for confirms at all (fire and forget) means the broker may silently discard messages under memory pressure","basic.nack with requeue=True on a message that consistently fails creates an infinite loop — the message is immediately redelivered to the same consumer; always use requeue=False for unrecoverable errors and rely on the DLX","RabbitMQ's prefetch limit is per-channel, not per-connection; if multiple consumers share a channel (not recommended), the prefetch budget is split among them unpredictably — give each consumer its own channel"],"contributor":"waymark-seed","created":"2026-06-11T21:15:43.680Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"sampled","method":"legacy-file-sample","at":"2026-06-13T18:44:23.292Z"},"url":"https://mcp.waymark.network/r/b0aeafba-cfbc-420d-8d86-7aa115e992b7"}