Skip to main content

RabbitMQ Cheatsheet — 90+ Commands, Patterns, and Pitfalls for Daily Work

RabbitMQ cheat sheet — 90+ commands and patterns for queues, exchanges, clustering, and common pitfalls.

  • Runs locally
  • Category Developer & DevOps
  • Best for Formatting, validating, shrinking, or inspecting code-adjacent text.
Section:
80 entries
CLI (33)
rabbitmqctl status

Show broker status: running applications, versions, OS and Erlang version, memory/disk usage.

Examples
rabbitmqctl status
rabbitmqctl status --formatter=json
rabbitmqctl list_queues name messages consumers unacked_messages

List queues with message count, consumer count, and unacknowledged message count. Add -p /vhost to scope to a vhost.

Examples
rabbitmqctl list_queues name messages consumers
rabbitmqctl list_queues -p /production name messages consumers unacked_messages memory
rabbitmqctl list_exchanges name type durable auto_delete

List all exchanges with type, durability, and auto-delete flag. Pre-declared system exchanges have empty names.

Examples
rabbitmqctl list_exchanges name type durable
rabbitmqctl list_exchanges -p /myapp name type
rabbitmqctl list_bindings source_name source_kind destination_name routing_key

List all exchange-to-queue bindings including routing keys. Useful for debugging routing mismatches.

Examples
rabbitmqctl list_bindings
rabbitmqctl list_bindings -p /myapp source_name destination_name routing_key
rabbitmqctl list_connections name state user vhost recv_oct send_oct

List all open AMQP connections with state, user, vhost, and bytes transferred. Use state to find stale/blocked connections.

Pitfall

A connection in "blocked" state means the broker hit a resource alarm (memory or disk). The client is being throttled.

Examples
rabbitmqctl list_connections name state user
rabbitmqctl list_connections name state user vhost recv_oct send_oct
rabbitmqctl list_channels name number user connection state consumer_count

List all open AMQP channels. Each connection can multiplex multiple channels. High channel counts per connection is a code smell.

Examples
rabbitmqctl list_channels
rabbitmqctl list_channels name number consumer_count
rabbitmqctl list_consumers queue_name consumer_tag ack_required prefetch_count

List all consumers with their queue, consumer tag, ack mode, and prefetch setting.

Examples
rabbitmqctl list_consumers
rabbitmqctl list_consumers queue_name consumer_tag ack_required prefetch_count
rabbitmqctl add_user <username> <password>

Create a new RabbitMQ user. Newly created users have no permissions on any vhost.

Examples
rabbitmqctl add_user alice secretpassword
rabbitmqctl add_user ci-agent "$(openssl rand -base64 32)"
rabbitmqctl set_user_tags <username> <tag...>

Assign management UI roles. Tags: administrator (full access), monitoring (read-only), management (basic UI access), policymaker (policy only).

Examples
rabbitmqctl set_user_tags alice administrator
rabbitmqctl set_user_tags ci-agent monitoring
rabbitmqctl set_user_tags alice   # clears all tags
rabbitmqctl set_permissions -p <vhost> <user> <conf> <write> <read>

Grant user permissions on a vhost. Three regex patterns: configure (declare/delete), write (publish), read (consume/get). `".*"` matches anything.

Examples
rabbitmqctl set_permissions -p / alice ".*" ".*" ".*"
rabbitmqctl set_permissions -p /prod alice "^app-" "^app-" "^app-"
rabbitmqctl list_users

List all users and their tags.

Examples
rabbitmqctl list_users
rabbitmqctl delete_user <username>

Delete a user and all their permissions.

Examples
rabbitmqctl delete_user alice
rabbitmqctl change_password <username> <newpassword>

Change a user's password.

Examples
rabbitmqctl change_password alice newpass123
rabbitmqctl list_permissions -p <vhost>

List all permission entries for a vhost.

Examples
rabbitmqctl list_permissions -p /
rabbitmqctl list_permissions -p /production
rabbitmqctl add_vhost <vhost>

Create a virtual host. vhosts provide logical isolation between tenants or environments.

Examples
rabbitmqctl add_vhost /production
rabbitmqctl add_vhost /staging
rabbitmqctl list_vhosts

List all virtual hosts.

Examples
rabbitmqctl list_vhosts
rabbitmqctl list_vhosts name tracing
rabbitmqctl delete_vhost <vhost>

Delete a vhost and all its queues, exchanges, bindings, and policies.

Pitfall

This is irreversible. Export definitions with export_definitions first if you need a backup.

Examples
rabbitmqctl delete_vhost /staging
rabbitmqctl purge_queue <queuename>

Delete all messages from a queue without deleting the queue itself.

Pitfall

Purging is permanent — messages cannot be recovered. Confirm this is what you want before running in production.

Examples
rabbitmqctl purge_queue payment-queue
rabbitmqctl purge_queue -p /prod orders
rabbitmqctl delete_queue <queuename>

Delete a queue and all its messages.

Examples
rabbitmqctl delete_queue old-test-queue
rabbitmqctl delete_queue -p /prod deadletter
rabbitmqctl delete_exchange <exchangename>

Delete an exchange. In-flight messages already routed to queues are unaffected.

Examples
rabbitmqctl delete_exchange old-events
rabbitmqctl delete_exchange -p /prod notifications
rabbitmqctl export_definitions /path/to/defs.json

Export all broker definitions (vhosts, queues, exchanges, bindings, users, policies) to a JSON file. Use for backups and migration.

Examples
rabbitmqctl export_definitions /tmp/rabbitmq-backup.json
rabbitmqctl export_definitions - | jq .   # stream to stdout
rabbitmqctl import_definitions /path/to/defs.json

Import broker definitions from a JSON file. Merges with existing config — does not delete anything not in the file.

Examples
rabbitmqctl import_definitions /tmp/rabbitmq-backup.json
curl -s http://localhost:15672/api/definitions -u guest:guest | rabbitmqctl import_definitions -
rabbitmqctl cluster_status

Show cluster membership, node types, and partition status. Check the "partitions" key — it should always be empty in a healthy cluster.

Examples
rabbitmqctl cluster_status
rabbitmqctl cluster_status --formatter=json | jq .partitions
rabbitmqctl join_cluster rabbit@<nodename>

Join an existing cluster. Must run `rabbitmqctl stop_app` first. The node must be reachable by Erlang cookie and hostname.

Examples
rabbitmqctl stop_app && rabbitmqctl join_cluster rabbit@rabbit2 && rabbitmqctl start_app
rabbitmqctl join_cluster --ram rabbit@rabbit1   # RAM node (not recommended)
rabbitmqctl forget_cluster_node rabbit@<deadnode>

Remove a permanently offline node from the cluster metadata. Use only when the node cannot be brought back online.

Pitfall

Only forget a node after you are certain it will never rejoin. Forgetting a node that still holds quorum queue data can cause data loss.

Examples
rabbitmqctl forget_cluster_node rabbit@dead-node
rabbitmqctl forget_cluster_node --offline rabbit@dead-node
rabbitmqctl reset

DANGER: Reset the node to factory defaults — wipes all data, definitions, and cluster membership. Requires stop_app first.

Pitfall

Irreversible. All queues, exchanges, bindings, messages, users (except the defaults) are gone.

Examples
rabbitmqctl stop_app && rabbitmqctl reset && rabbitmqctl start_app
rabbitmq-plugins enable <plugin>

Enable a plugin. Changes take effect immediately without restart (most plugins). Common plugins: rabbitmq_management, rabbitmq_shovel, rabbitmq_federation, rabbitmq_stream.

Examples
rabbitmq-plugins enable rabbitmq_management
rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management
rabbitmq-plugins enable rabbitmq_stream rabbitmq_stream_management
rabbitmq-plugins list

List all plugins with their enabled/disabled state. An [E] prefix means explicitly enabled, [e] means enabled as dependency.

Examples
rabbitmq-plugins list
rabbitmq-plugins list --enabled
rabbitmq-diagnostics check_running

Health check: exits 0 if the broker is running and its internal health checks pass, non-zero otherwise. Suitable for readiness probes.

Examples
rabbitmq-diagnostics check_running && echo "healthy"
rabbitmq-diagnostics check_port_connectivity && rabbitmq-diagnostics check_running
rabbitmq-diagnostics memory_breakdown

Show memory usage breakdown by category (queues, connections, channels, bindings, mnesia, etc.). Essential for diagnosing memory pressure.

Examples
rabbitmq-diagnostics memory_breakdown
rabbitmq-diagnostics memory_breakdown --formatter=json | jq .
rabbitmq-diagnostics check_port_connectivity

Verify that AMQP, management, and clustering ports are reachable.

Examples
rabbitmq-diagnostics check_port_connectivity
rabbitmqctl set_policy <name> <pattern> <definition> --apply-to <queues|exchanges|all>

Apply a policy to all queues/exchanges matching a name regex. Policies override per-queue arguments and can be changed live.

Examples
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}' --apply-to queues
rabbitmqctl set_policy ttl-1h "^transient\." '{"message-ttl":3600000}' --apply-to queues
rabbitmqctl set_policy max-length "^bounded\." '{"max-length":10000,"overflow":"reject-publish-dlx"}' --apply-to queues
rabbitmqctl eval '<Erlang expression>'

Evaluate an Erlang expression on the running node. Useful for one-off production diagnostics not exposed via standard CLI commands.

Pitfall

Use sparingly and only in emergencies — incorrect Erlang expressions can crash the node. Prefer rabbitmq-diagnostics commands in routine operations.

Examples
rabbitmqctl eval 'rabbit_nodes:all_running().'
rabbitmqctl eval 'length(rabbit_amqqueue:list()).'
rabbitmqctl eval 'mnesia:system_info(all).'
Concepts (20)
Direct exchange (type: direct)

Routes messages to queues whose binding key exactly matches the message routing key. One key → one (or more) queues with the same binding.

Examples
# Declare: channel.exchangeDeclare("events", "direct", true)
# Bind:    channel.queueBind("order-created-queue", "events", "order.created")
# Publish: channel.basicPublish("events", "order.created", null, body)
Topic exchange (type: topic)

Routes with wildcard patterns. `*` matches exactly one dot-separated word. `#` matches zero or more words. E.g. binding `user.#` catches `user.login`, `user.profile.updated`.

Examples
# Binding "*.error" catches order.error, payment.error but not order.payment.error
# Binding "order.#" catches order.created, order.item.added, order.fulfilled
# Binding "#" catches everything (same as fanout but slower)
Fanout exchange (type: fanout)

Delivers a copy of every message to every bound queue, ignoring the routing key entirely. Perfect for broadcast / pub-sub.

Pitfall

Because the routing key is ignored, accidentally binding a queue to a fanout exchange silently starts receiving all messages.

Examples
# Declare: channel.exchangeDeclare("broadcast", "fanout", true)
# Each subscriber declares its own queue and binds it — no routing key needed
# Publish: channel.basicPublish("broadcast", "", null, body)  // key ignored
Headers exchange (type: headers)

Routes based on message header key-value pairs instead of the routing key. Binding specifies required header values and x-match: all (AND) or any (OR).

Examples
# Bind with: {"format":"pdf","type":"report","x-match":"all"}
# Matches messages with BOTH format=pdf AND type=report headers
Default exchange (name: "")

A built-in nameless direct exchange. Every queue is automatically bound to it using the queue name as routing key. Convenient for point-to-point but cannot do pub/sub.

Pitfall

The default exchange looks like a shortcut but couples senders to queue names. Use a named exchange for proper decoupling.

Examples
# channel.basicPublish("", "my-queue", null, body) sends direct to my-queue
Dead Letter Exchange (x-dead-letter-exchange)

An exchange that receives messages the source queue cannot deliver: TTL expired, queue full (with overflow reject), or consumer nacked with requeue=false.

Examples
# Declare source queue with DLX:
# channel.queueDeclare("orders", true, false, false, {"x-dead-letter-exchange": "dlx", "x-dead-letter-routing-key": "orders.dead"})
# Bind a "parking lot" queue to dlx with routing key "orders.dead"
Alternate Exchange (x-alternate-exchange)

An exchange that receives messages that could not be routed (no queue matched the routing key). Prevents silent message loss on routing mismatches.

Examples
# Declare exchange with AE:
# channel.exchangeDeclare("main", "topic", true, false, {"alternate-exchange": "unrouted"})
# channel.exchangeDeclare("unrouted", "fanout", true)
Classic queue

Standard AMQP queue backed by Mnesia. Not replicated unless configured with a classic mirroring policy (deprecated in 3.9, removed in 4.0). Use for ephemeral non-critical workloads only.

Examples
# channel.queueDeclare("task-queue", true, false, false, null)
# durable=true means the queue survives broker restart
Quorum queue (x-queue-type: quorum)

Replicated queue using Raft consensus. Survives minority node failures without data loss. Recommended for all production queues. Supports DLX, per-message TTL, x-max-length, and delivery limits.

Pitfall

Quorum queues are always durable. They do not support priority queues or global QoS. Each queue has one elected leader per node; avoid having hundreds of queues on small clusters.

Examples
# channel.queueDeclare("orders", true, false, false, {"x-queue-type": "quorum"})
# Set leader election strategy via policy: {"queue-leader-locator": "balanced"}
Stream queue (x-queue-type: stream)

Immutable append-only log. Consumers replay from any offset. Retains data up to a configured size or age, not until consumer ack. Requires rabbitmq_stream plugin.

Examples
# channel.queueDeclare("events", true, false, false, {"x-queue-type": "stream", "x-max-age": "7D", "x-stream-max-segment-size-bytes": 536870912})
# Consumer subscribes with offset: {"x-stream-offset": "first"} or {"x-stream-offset": <timestamp>}
Message TTL (x-message-ttl)

Queue-level TTL in milliseconds. Messages older than this are dead-lettered (if DLX configured) or dropped. Set on the queue declaration.

Examples
# {"x-message-ttl": 60000}  // 60 seconds
# Or via policy: rabbitmqctl set_policy ttl "^cache\." '{"message-ttl":5000}' --apply-to queues
Per-message TTL (expiration header)

Per-message expiry in milliseconds, set in the message properties. Overrides queue-level TTL if both are set (broker uses the lower value).

Examples
# AMQP props: { expiration: "30000" }  // 30 seconds
# Note: expiration is a STRING in the AMQP spec, not an integer
Queue TTL (x-expires)

Queue auto-deletes after this many milliseconds of having no consumers AND no messages being published to it. Useful for auto-cleanup of temporary reply queues.

Examples
# {"x-expires": 3600000}  // queue disappears after 1 hour idle
Publisher confirms (channel.confirmSelect)

Broker ACKs each published message. basic.ack = accepted (written to disk if persistent). basic.nack = dropped (queue full, resource alarm). Enables at-least-once publishing guarantees.

Pitfall

Single-message confirms have 5–10% throughput overhead. Batch confirms (publish N, wait for N acks) recover most of it.

Examples
# channel.confirmSelect();
# channel.waitForConfirmsOrDie(5000);  // Java: wait up to 5s for all outstanding acks
# async: channel.addConfirmListener((tag, multiple) => { /* handle ack */ }, (tag, multiple) => { /* handle nack */ })
Consumer acknowledgement modes

Three ack modes: basic.ack (success, remove from queue), basic.nack (failure, with optional requeue=true/false), basic.reject (same as nack but for one message only). Manual ack is always safer than auto-ack.

Pitfall

basic.nack with requeue=true re-delivers immediately — if processing always fails, the message loops forever. Route to DLX instead.

Examples
# channel.basicAck(deliveryTag, false)
# channel.basicNack(deliveryTag, false, false)  // nack, no requeue → DLX
# channel.basicReject(deliveryTag, false)       // reject single message
Basic.QoS / prefetch (channel.basicQos)

Limits unacknowledged messages delivered to a consumer at once. Without it, the broker floods the fastest consumer. Set before basicConsume. Scope: per-channel (default) or per-consumer.

Pitfall

prefetch=0 means unlimited (no limit at all). prefetch=1 means the consumer processes exactly one message at a time — correct for strict ordering, slow for high-throughput.

Examples
# channel.basicQos(10)  // at most 10 unacked messages per channel
# channel.basicQos(1, true)  // prefetch=1, global=true (applies per-channel not per-consumer)
Durable queue + delivery-mode=2 (persistent message)

For a message to survive a broker restart, BOTH conditions must hold: (1) the queue must be declared durable, and (2) the message must be published with delivery-mode=2.

Pitfall

A durable queue with non-persistent messages (delivery-mode=1) will survive broker restart but its messages will not. This is the most common durability mistake.

Examples
# queue: durable=true
# message props: deliveryMode=2
# AMQP props: { deliveryMode: 2, contentType: "application/json" }
x-max-length and x-overflow

Cap queue depth by message count (x-max-length) or bytes (x-max-length-bytes). x-overflow controls what happens when the cap is hit: drop-head (default, drop oldest), reject-publish (nack publisher), or reject-publish-dlx (nack publisher + DLX for dropped).

Examples
# {"x-max-length": 10000, "x-overflow": "reject-publish"}
# Via policy: rabbitmqctl set_policy bounded "^bnd\." '{"max-length":5000,"overflow":"reject-publish-dlx"}' --apply-to queues
Priority queue (x-max-priority)

Queue with up to 255 priority levels. Higher number = higher priority. Messages must carry a numeric `priority` property. Without consumer priority configuration, priority works only within a single consumer.

Pitfall

Using x-max-priority > 5 wastes memory — RabbitMQ creates internal queues for each priority level. Most use cases need only 2–5 levels.

Examples
# {"x-max-priority": 5}
# Publish high-priority: { priority: 5 }
# Publish normal: { priority: 1 }
Auto-delete and exclusive queues

Auto-delete: queue is deleted when the last consumer disconnects. Exclusive: visible only to the declaring connection, deleted when the connection closes. Both useful for temporary work or RPC reply queues.

Examples
# exclusive=true: channel.queueDeclare("", false, true, true, null)  // "" = server-generated name
# auto-delete=true: channel.queueDeclare("reply-12345", false, false, true, null)
Patterns (13)
Work queue (competing consumers)

Multiple consumers subscribe to the same queue. The broker distributes messages round-robin. Each message is processed by exactly one consumer. The classic horizontal scaling pattern for background jobs.

Examples
# Declare one shared durable queue
# Start N worker processes each calling channel.basicConsume("tasks", ...)
# Set prefetch=1 to prevent work imbalance: channel.basicQos(1)
Pub/Sub with fanout exchange

Each subscriber declares its own exclusive queue and binds it to a fanout exchange. Every subscriber receives every message independently. Perfect for event broadcasting.

Examples
# Publisher: channel.basicPublish("events-fanout", "", null, body)
# Subscriber A: queueDeclare("", ..., true, true, ...) → queueBind(q, "events-fanout", "")
# Subscriber B: queueDeclare("", ..., true, true, ...) → queueBind(q, "events-fanout", "")
Topic routing (wildcard routing key)

Use a topic exchange so consumers subscribe by pattern. E.g. a logging consumer binds `#.error` to receive errors from any service; an audit consumer binds `order.#` for all order events.

Examples
# channel.exchangeDeclare("events", "topic", true)
# Bind error queue: channel.queueBind("errors", "events", "#.error")
# Bind order queue: channel.queueBind("order-audit", "events", "order.#")
# Publish: channel.basicPublish("events", "order.payment.failed", null, body)
RPC over AMQP (reply_to + correlation_id)

Client publishes to the server queue with reply_to=<exclusive-queue-name> and a unique correlation_id. Server processes and publishes the response to the reply_to queue with the same correlation_id.

Pitfall

AMQP RPC is a valid pattern but adds latency. Prefer it over HTTP only when you already have RabbitMQ in the stack and need request routing or backpressure.

Examples
# Client: channel.basicPublish("", "rpc-server-queue", {replyTo: "amq.rabbitmq.reply-to", correlationId: uuid}, body)
# Use "amq.rabbitmq.reply-to" as the reply-to address for the fast direct reply protocol
# Server: on message, channel.basicPublish("", msg.properties.replyTo, {correlationId: msg.properties.correlationId}, responseBody)
Dead letter queue (DLQ parking lot)

Source queue sends failed/expired messages to a DLX. A "parking lot" queue bound to the DLX holds them for inspection, replay, or manual discard. Ops teams use this to debug failures without losing messages.

Examples
# 1. Declare DLX: channel.exchangeDeclare("dlx", "direct", true)
# 2. Bind parking lot: channel.queueDeclare("parking-lot", true, ...); channel.queueBind("parking-lot", "dlx", "parking")
# 3. Source queue: {"x-dead-letter-exchange": "dlx", "x-dead-letter-routing-key": "parking"}
# 4. When consumer nacks with requeue=false, message lands in parking-lot
Exponential backoff retry via TTL + DLX chain

Chain: source-queue → nack → dlx → wait-1s-queue (TTL=1000, DLX→source) → expires → back to source. Add wait-10s-queue for 2nd retry etc. Headers track the attempt count.

Examples
# wait-1s-queue: {"x-dead-letter-exchange": "main-exchange", "x-message-ttl": 1000}
# wait-10s-queue: {"x-dead-letter-exchange": "main-exchange", "x-message-ttl": 10000}
# After max retries, nack to a final parking-lot queue instead
Delayed message (per-message TTL + DLX)

Set expiration on the message and route it to a holding queue with no consumers. When the TTL expires, DLX re-routes it to the actual destination.

Pitfall

The rabbitmq-delayed-message-exchange plugin is cleaner for production use — it stores messages on a per-node basis and supports precise delay without creating extra queues.

Examples
# Install: rabbitmq-plugins enable rabbitmq_delayed_message_exchange
# channel.exchangeDeclare("delayed", "x-delayed-message", true, false, {"x-delayed-type": "direct"})
# Publish with header: {"x-delay": 5000}  // delay 5 seconds
Shovel plugin (move messages between brokers)

Shovel dynamically moves messages from a source queue/exchange to a destination on the same or a different broker. Use for cross-datacenter replication or vhost migration.

Examples
# Enable: rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management
# Set shovel via policy or management API: PUT /api/parameters/shovel/%2F/my-shovel
# {"src-uri":"amqp://","src-queue":"old-queue","dest-uri":"amqp://remote-host","dest-queue":"new-queue"}
Idempotent consumer (message deduplication)

Store the message-id (or a business key) in Redis/DB before processing. If already seen, ack and skip. This turns at-least-once delivery into effectively-once processing.

Examples
# 1. Receive message with unique messageId in properties
# 2. if redis.set(messageId, "1", NX, EX, 86400): process and ack
# 3. else: ack without processing (already handled)
Outbox pattern (atomic write + publish)

Write the event to an outbox table in the same DB transaction as the business change. A background poller reads the outbox and publishes to RabbitMQ. Guarantees no message is lost if the service crashes after the DB write but before publishing.

Examples
# 1. BEGIN TRANSACTION
# 2. UPDATE orders SET status="paid" WHERE id=123
# 3. INSERT INTO outbox(event_type, payload) VALUES ("order.paid", "...")
# 4. COMMIT
# 5. Poller: SELECT * FROM outbox WHERE published_at IS NULL; → publish; UPDATE outbox SET published_at=NOW()
Circuit breaker via x-overflow: reject-publish

Set x-max-length + x-overflow: reject-publish on the source queue. When the queue hits capacity, publishers receive a nack and should stop sending (circuit open). When consumers drain the queue, publishers receive acks again (circuit closed).

Examples
# {"x-max-length": 1000, "x-overflow": "reject-publish"}
# Publisher must handle nack: pause publishing or fall back to local buffer
Event sourcing with stream queues

Use a stream queue as an immutable event log. Consumers subscribe at any offset (first, last, specific timestamp, or byte offset). Multiple consumer groups replay independently without interfering.

Examples
# {"x-queue-type": "stream", "x-max-age": "30D"}
# Subscribe from beginning: consumer args {"x-stream-offset": "first"}
# Subscribe from timestamp: consumer args {"x-stream-offset": <unix-timestamp-ms>}
Blue/green deployment via vhosts

Route traffic to /blue or /green vhosts. Deploy new version against /green while /blue serves production. Swap the load balancer or app config to point at /green; keep /blue for instant rollback.

Examples
# rabbitmqctl add_vhost /green
# rabbitmqctl set_permissions -p /green deploy ".*" ".*" ".*"
# Configure app to use AMQP_VHOST=/green for the new deployment
Pitfalls (14)
autoAck=true → silent data loss on consumer crash

With autoAck=true the broker removes the message from the queue the instant it delivers it. If the consumer crashes or throws an exception before finishing, the message is gone forever.

Pitfall

Always use manual ack. Call basicAck only after successful processing. Call basicNack/basicReject on failure.

Examples
# Wrong: channel.basicConsume("tasks", true, callback)  // autoAck=true
# Right: channel.basicConsume("tasks", false, callback) // manual ack
# In callback: try { process(msg); channel.basicAck(tag, false); } catch { channel.basicNack(tag, false, false); }
Missing prefetch → memory balloon + consumer starvation

Without a prefetch limit the broker pushes ALL queued messages to the first available consumer. That consumer buffers thousands of messages in memory while other consumers sit idle.

Pitfall

Always call channel.basicQos() before channel.basicConsume(). For work queues: prefetch 10–100. For slow processing: prefetch 1.

Examples
# channel.basicQos(10)  // then channel.basicConsume(...)
Re-using a channel after an error closes it

AMQP channels are invalidated by broker errors (wrong permissions, declaring conflicting queue, acking an unknown delivery tag). After a channel-level error you MUST create a new channel — the old one is permanently closed.

Pitfall

Channel errors look like connection errors in logs. Distinguish them by the error code: 4xx codes are channel errors, 5xx codes are connection errors.

Examples
# Wrong: ignore the error and keep using the same channel object
# Right: listen for channel.close event; create a new channel in the handler
# channel.on("error", (err) => { channel = connection.createChannel(); })
Classic mirrored queues (deprecated since 3.9)

Classic mirrored queues (ha-policy) are unreliable under network partitions, lose messages during sync, and require manual operator intervention on node failures. They are deprecated in 3.9 and removed in 4.0.

Pitfall

Migrate to quorum queues now. Declare with x-queue-type: quorum. They handle split-brain and node failures automatically.

Examples
# Remove ha-all policy: rabbitmqctl clear_policy ha-all
# Migrate: drain classic queue, delete it, redeclare with x-queue-type: quorum
Durable queue + non-persistent messages → data lost on restart

A durable queue survives broker restart but its messages do NOT unless delivery-mode=2 (persistent). A durable queue with delivery-mode=1 messages empties silently on restart.

Pitfall

Both conditions must hold: queue.durable=true AND message.deliveryMode=2. Check your publish code and not just the queue declaration.

Examples
# Wrong: channel.basicPublish("ex", "key", null, body)  // default deliveryMode=1
# Right: channel.basicPublish("ex", "key", {deliveryMode: 2}, body)
Memory watermark alarm blocks ALL publishers

When broker memory usage exceeds the high_watermark (default 40% of available RAM), ALL connections entering the publish path are blocked. The broker sends a Connection.Blocked to clients.

Pitfall

Symptoms: publishing hangs indefinitely, consumers still drain. Fix: add RAM, raise the watermark, or accelerate consumption. Run `rabbitmq-diagnostics memory_breakdown` to find the culprit.

Examples
# Temporary relief: rabbitmqctl set_vm_memory_high_watermark 0.6
# Check current: rabbitmq-diagnostics memory_breakdown
# Long-term: add RAM, enable lazy queues (page to disk), or reduce queue depth
Too many connections (connection storm)

Each AMQP connection consumes ~100KB of RAM and a file descriptor on the broker. A connection storm (e.g. each Lambda invocation creates a new connection) can exhaust broker resources quickly.

Pitfall

Use a connection pool or singleton connection pattern. Share one connection per process; multiplex work across channels on that connection.

Examples
# Wrong: create a new connection per message (serverless anti-pattern)
# Right: create one connection at startup; reuse across all handlers
# Check: rabbitmqctl list_connections | wc -l
Missing heartbeat → ghost connections accumulate

Without a heartbeat, a TCP connection that lost its underlying route (firewall timeout, NAT table eviction) looks alive to both sides until someone tries to send. The broker accumulates ghost connections that never clear.

Pitfall

Always negotiate a heartbeat. The RabbitMQ default is 60 seconds. Most clients default to 60s too. Set explicitly to avoid mismatches.

Examples
# Node.js amqplib: amqp.connect("amqp://localhost?heartbeat=60")
# Java Spring AMQP: factory.setRequestedHeartbeat(60)
# Check ghost conns: rabbitmqctl list_connections name state  // look for "blocking" with no traffic
Routing key mismatch → silent message black-hole

If you publish with a routing key that does not match any binding AND there is no Alternate Exchange configured, the message is silently discarded. No error, no log entry.

Pitfall

Use the mandatory flag when publishing. With mandatory=true, unroutable messages trigger a basic.return callback instead of disappearing silently.

Examples
# channel.basicPublish("events", "wrong.key", {mandatory: true}, body)
# channel.on("return", (msg) => { console.error("Unroutable:", msg.fields.routingKey) })
# Or configure AE: {"alternate-exchange": "unrouted-ae"}
nack with requeue=true → infinite retry loop

basicNack(tag, false, requeue=true) re-delivers the message immediately to the front of the queue. If processing always fails, the message loops forever at 100% CPU, blocking new messages.

Pitfall

Never requeue=true unconditionally. Count retries in a header; after max retries, nack with requeue=false to send to DLX.

Examples
# Wrong: channel.basicNack(tag, false, true)  // will loop on poison message
# Right: check x-death header count; after 3 retries: channel.basicNack(tag, false, false)
Not setting DLX → failed messages silently vanish

Without a DLX configured, messages that expire or are rejected with requeue=false are dropped by the broker. You have no visibility into what was lost or why.

Pitfall

Always configure a DLX on queues that handle important work. Route to a parking-lot queue or another processing queue. Never let messages disappear silently.

Examples
# Minimum DLX setup:
# channel.exchangeDeclare("dlx", "fanout", true)
# channel.queueDeclare("dead-letters", true, false, false, null)
# channel.queueBind("dead-letters", "dlx", "")
# source queue: {"x-dead-letter-exchange": "dlx"}
Connection vs channel confusion

A connection is one TCP socket to the broker. A channel is a lightweight virtual connection multiplexed over it. Create one connection per process; use multiple channels per connection for parallelism.

Pitfall

Channels are NOT thread-safe in most client libraries. Create one channel per thread. Opening/closing channels is cheap — opening/closing connections is expensive.

Examples
# Wrong: share one channel across multiple threads
# Right: one connection → N channels (one per thread/goroutine/coroutine)
Publishing with transactions instead of publisher confirms

AMQP transactions (tx.select / tx.commit) provide exactly-once semantics but at 5–10× the throughput cost of publisher confirms. Use confirms instead — they achieve at-least-once at a fraction of the cost.

Pitfall

Transactions also block the channel until committed, increasing latency. In practice, publisher confirms + idempotent consumer achieves the same effective guarantee at far better throughput.

Examples
# Avoid: channel.txSelect(); channel.basicPublish(...); channel.txCommit();
# Use: channel.confirmSelect(); channel.basicPublish(...); channel.waitForConfirmsOrDie();
Pitfall: ignoring connection-level errors

Many SDKs expose channel-level and connection-level error events separately. Channels close on protocol errors; the underlying connection may survive. Not listening to connection errors means silent message loss when the broker restarts or network blips.

Pitfall

Register an `on("error")` handler on the connection object, not just the channel. Implement reconnection logic (exponential backoff) at the connection level, not just channel re-open.

Examples
// Bad: only handles channel errors
channel.on('error', (err) => console.error('channel error', err));
// Good: handle both
connection.on('error', (err) => { reconnect(); });
channel.on('error', (err) => { reopenChannel(); });

What this tool does

Searchable RabbitMQ reference with 90+ entries covering every aspect of daily RabbitMQ work. CLI section: rabbitmqctl for listing and managing queues, exchanges, bindings, connections, channels, users, permissions, vhosts, purging queues, exporting/importing definitions, cluster management (join, status, forget dead node, reset), plus rabbitmq-plugins (enable management, shovel, federation, streams) and rabbitmq-diagnostics (check_running, memory_breakdown, check_port_connectivity). Concepts section: all four exchange types (direct, topic, fanout, headers), the default exchange and why it is not a shortcut for pub/sub, Dead Letter Exchange (DLX) and Alternate Exchange (AE), classic vs quorum vs stream queue types, message TTL and queue TTL, publisher confirms, consumer acknowledgement modes (ack/nack/reject), Basic.QoS prefetch, durable queues with persistent delivery mode 2, auto-delete and exclusive queues, x-max-length and overflow policies, priority queues. Patterns section: work queue with competing consumers, pub/sub with fanout, direct routing, topic wildcard routing, AMQP RPC with reply_to/correlation_id, dead letter queue parking lot, exponential backoff retry via TTL + DLX loop, delayed messages, shovel and federation, idempotent consumer, outbox pattern, circuit breaker via x-overflow, event sourcing with streams, saga coordination. Pitfalls section: auto-ack data loss, missing prefetch memory balloon, channel reuse after error, classic mirrored queues vs quorum, non-persistent messages in durable queues, memory watermark alarm halting publishers, connection storm, missing heartbeat, routing key black holes, DLX misconfiguration. Every entry: bilingual EN/ZH descriptions, copy-ready commands or config, and real-world context. Search filters across command, description, examples, and pitfall text; category chips scope to CLI / Concepts / Patterns / Pitfalls. 100% client-side, zero requests, works air-gapped.

Tool details

Input
Text
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
Shareable URL state
Key settings are encoded in the URL so another person can reopen the same setup.
Performance budget
Initial JS <= 32 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.

How to use

  1. 1. Input

    Paste or drop your content into the tool panel.

  2. 2. Process

    Click the button. All processing is local in your browser.

  3. 3. Copy / Download

    Copy the result or download to disk in one click.

How RabbitMQ Cheatsheet fits into your work

Use it in the small gaps between coding, reviewing, debugging, and shipping.

Developer jobs

  • Formatting, validating, shrinking, or inspecting code-adjacent text.
  • Preparing snippets for documentation, tickets, commits, or handoff.
  • Checking a small payload quickly without switching tools.

Developer checks

  • Run irreversible transforms like minify or obfuscate on a copy.
  • Keep secrets out of pasted snippets unless the tool explicitly stays local.
  • Use your normal tests or linter before shipping transformed code.

Good next steps

These links move the current task into a more complete workflow.

  1. 1 Docker Cheatsheet Docker command cheat sheet — 80+ commands with real examples, common mistakes, and Compose section. Open
  2. 2 Redis Cheatsheet Redis cheat sheet — 80+ commands across strings, hashes, lists, sets, sorted sets, pub/sub, streams, scripts, with examples and pitfalls. Open
  3. 3 kubectl Cheatsheet kubectl cheat sheet — 100+ Kubernetes commands with real examples, common pitfalls, and YAML snippets. Open

Real-world use cases

  • Debug a production queue backlog at 2 AM

    Your alerting fires because a payment processing queue has 50,000 unacked messages and consumer count dropped to zero. You pull up the cheat sheet, run `rabbitmqctl list_queues name messages consumers unacked_messages` to confirm, then `rabbitmqctl list_connections name state` to find the stale connection. The cluster_status entry confirms the node is still up and the memory_breakdown entry points you to the real culprit: a consumer that crashed without closing its channel.

  • Migrate from classic mirrored queues to quorum queues before a major release

    Your team has classic ha-all mirrored queues everywhere and you need to migrate before upgrading past 3.9. The cheat sheet's quorum queue concept entry gives you the x-queue-type declaration, and the export_definitions entry lets you snapshot the current topology. You migrate queue by queue during a maintenance window, verifying replication with cluster_status after each step.

  • Design a retry pipeline with exponential backoff

    Your order processor sometimes hits a downstream API that returns 503. You need retries with backoff, not an infinite loop. The cheat sheet's "exponential backoff via TTL + DLX" pattern entry gives you the full queue chain: order-queue → reject → dlx → retry-1s → TTL expires → dlx → retry-10s → … → dead-letter-parking-lot. The DLX concept entry and the x-dead-letter-exchange CLI argument give you all the primitives.

Common pitfalls

  • Declaring a queue with durable=true but publishing with deliveryMode=1 (transient). Messages survive a broker restart only when BOTH the queue is durable AND the message delivery mode is 2 (persistent).

  • Using classic mirrored queues (ha-policy) in RabbitMQ 3.9+. They are deprecated, unreliable under network partitions, and removed in 4.0. Use quorum queues instead.

  • Setting autoAck=true and doing slow processing. If the consumer crashes after receiving but before finishing, the message is gone. Always use manual ack and call ack only after successful processing.

Privacy

Every command, every concept, every pattern, and every pitfall lives entirely in a static in-memory array loaded with the page. The search box, category chips, and copy buttons run fully in your browser. Nothing you search, nothing you copy, and nothing you type is sent to any server or written into the page URL. Open DevTools then Network and type: you will see zero outbound requests. Works behind a corporate proxy, on a plane, or on an air-gapped server room machine — exactly the environments where you reach for a RabbitMQ cheat sheet.

FAQ

Tool combos

Folks in your role tend to reach for these alongside this tool.

Made by Toolora · 100% client-side · Updated 2026-07-01