How to Install RabbitMQ on Ubuntu 24.04 VPS: AMQP Message Broker for Reliable Queues
RabbitMQ is the most widely deployed open-source message broker in the world, and for good reason: it speaks AMQP 0-9-1, AMQP 1.0, MQTT, STOMP, and its own high-throughput Streams protocol, it has been battle-tested at scale by companies like Reddit and AT&T, and modern versions built on Erlang/OTP 26+ handle millions of messages per second on modest hardware. This guide walks you through installing RabbitMQ on a clean Ubuntu 24.04 LTS VPS from scratch: adding the Erlang and RabbitMQ apt repositories hosted on Cloudsmith, configuring users, vhosts and permissions, declaring exchanges, quorum queues and bindings, and finishing with TLS, the management UI, and high-availability clustering.
Prefer a one-command install? Our CloudCore Starter plan comes with Ubuntu 24.04 pre-configured and enough headroom to run RabbitMQ, your application, and monitoring on the same node. Deploy it in 60 seconds and follow this guide.
Table of Contents
What is RabbitMQ?
RabbitMQ is a distributed message broker written in Erlang/OTP. At its core it accepts messages from publishers, routes them through exchanges to one or more queues based on bindings and routing keys, and delivers them to consumers. That decoupling, asynchronous producer and consumer, is the foundation of almost every modern scalable architecture: background jobs, email pipelines, order processing, IoT telemetry, log aggregation, RPC, and event-driven microservices.
Unlike Apache Kafka, which is a partitioned commit log, RabbitMQ's traditional strength is smart routing and per-message acknowledgements for at-least-once delivery. Modern RabbitMQ (4.x) adds two queue types that compete directly with Kafka and NATS JetStream: quorum queues (Raft-replicated, durable, the new default for HA) and streams (append-only logs with replay, built for high-throughput fan-out).
RabbitMQ speaks multiple protocols on the same broker:
- AMQP 0-9-1 -- the classic RabbitMQ protocol, universally supported by client libraries.
- AMQP 1.0 -- an OASIS standard, useful for interop with Azure Service Bus and Apache Qpid.
- MQTT 3.1.1 / 5.0 -- IoT pub/sub, enabled by a plugin.
- STOMP -- a simple text protocol often used in browser WebSocket bridges.
- RabbitMQ Streams protocol -- a binary, partition-friendly protocol on port 5552 for the Streams feature.
Why Self-Host RabbitMQ vs CloudAMQP?
CloudAMQP is a managed RabbitMQ-as-a-service that removes some operational burden. It is a good fit for very early-stage teams with no Linux experience. Once you pass the hobby tier, the economics tilt hard toward self-hosting.
- Cost per throughput -- A CloudAMQP "Bunny" plan (1000 msg/sec, 100 connections) costs roughly EUR 99/month. The same workload runs comfortably on a CloudCore Starter VPS at EUR 7.99/month with plenty of headroom.
- Data residency -- Managed RabbitMQ often runs in shared AWS/GCP regions. Self-hosting keeps message payloads -- which often include PII, order data, or auth tokens -- on infrastructure you control.
- No per-connection pricing -- CloudAMQP charges by concurrent connections. RabbitMQ on your own VPS happily handles 10,000+ connections per node with no additional fee.
- Full plugin control -- You can enable
rabbitmq_shovel,rabbitmq_federation,rabbitmq_stream,rabbitmq_mqtt,rabbitmq_consistent_hash_exchange, and community plugins. Managed offerings restrict plugin choice. - Erlang VM tuning -- Self-hosted RabbitMQ lets you tune scheduler threads (
+S), async threads (+A), and distribution buffer size (+zdbbl) for your specific workload. - No noisy neighbours -- Shared AMQP SaaS sometimes has latency spikes when another tenant saturates a shared broker. A dedicated VPS gives you predictable p99.
- Lock-in freedom -- Your cluster runs on Ubuntu with the official apt packages. Migrating between providers (or back to on-prem) is a tar-and-rsync exercise, not a vendor export.
Cost Comparison
| Workload | CloudAMQP | AWS MQ (RabbitMQ) | Self-Hosted (CloudCore Starter) |
|---|---|---|---|
| 500 msg/sec, 50 connections | EUR 49/mo | EUR 85/mo | EUR 7.99/mo |
| 5000 msg/sec, 500 connections | EUR 199/mo | EUR 280/mo | EUR 14.99/mo (CloudCore Professional) |
| 20k msg/sec + HA cluster | EUR 599/mo | EUR 650/mo | EUR 45/mo (3x CloudCore nodes) |
Prerequisites
Before starting you need:
- An Ubuntu 24.04 LTS VPS with root or sudo access.
- SSH access and a basic familiarity with the Linux command line.
- At least 1 GB RAM for a minimal broker (4 GB recommended for production).
- At least 10 GB free disk for messages, queue indexes, and logs.
- A public DNS hostname (optional, but required for the TLS and management UI sections).
Recommended Plan: CloudCore Starter>
For a single-node broker running hundreds of queues and a few thousand messages per second, the CloudCore Starter plan is the right entry point:>
- 2 vCPU cores
- 4 GB RAM
- 50 GB NVMe SSD
- Unmetered bandwidth
- From EUR 7.99/month>
For a 3-node HA cluster, provision three CloudCore Starter or Professional instances in the same region.
Connect to your server:
ssh root@your-server-ipStep 1: Update System Packages
Always start with a full package update so apt has the latest indexes and any security patches are applied:
sudo apt update && sudo apt upgrade -yInstall the prerequisites we will need for fetching GPG keys and TLS-enabled apt transport:
sudo apt install -y curl gnupg apt-transport-https ca-certificates lsb-releaseIf the kernel was updated, reboot before continuing:
sudo rebootStep 2: Add the Erlang Apt Repository
RabbitMQ requires a specific, recent Erlang/OTP version (26 or 27 for RabbitMQ 4.x). The Erlang packages shipped in Ubuntu's default repository are usually too old. The RabbitMQ team publishes a curated Erlang build on Cloudsmith that is known to work with current RabbitMQ releases.
Import the Cloudsmith Erlang signing key:
sudo mkdir -p /etc/apt/keyrings
curl -1sLf "https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-erlang.E495BB49CC4BBE5B.key" | \
sudo gpg --dearmor -o /usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpgCreate the Erlang apt source list:
sudo tee /etc/apt/sources.list.d/rabbitmq-erlang.list > /dev/null <<'EOF'
Provides modern Erlang/OTP releases from Cloudsmith
deb [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu noble main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.E495BB49CC4BBE5B.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu noble main
EOFNote the noble codename -- that is Ubuntu 24.04. Confirm your codename with lsb_release -cs if unsure.
Step 3: Add the RabbitMQ Apt Repository
Now add the RabbitMQ server repository, also on Cloudsmith:
curl -1sLf "https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-server.9F4587F226208342.key" | \
sudo gpg --dearmor -o /usr/share/keyrings/rabbitmq.9F4587F226208342.gpgsudo tee /etc/apt/sources.list.d/rabbitmq-server.list > /dev/null <<'EOF'
Provides RabbitMQ 4.x from Cloudsmith
deb [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu noble main
deb-src [signed-by=/usr/share/keyrings/rabbitmq.9F4587F226208342.gpg] https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu noble main
EOFRefresh apt:
sudo apt updateExpected output includes the two new repositories:
Get:1 https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu noble InRelease
Get:2 https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu noble InRelease
...Step 4: Install RabbitMQ Server
Install Erlang and RabbitMQ in a single command. Using --fix-missing avoids partial installs if one of the Erlang sub-packages is missing on a mirror:
sudo apt install -y --fix-missing \
erlang-base \
erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-inets \
erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
erlang-runtime-tools erlang-snmp erlang-ssl \
erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl \
rabbitmq-serverThe systemd unit is enabled and started automatically by the postinst script. Confirm it is running:
sudo systemctl status rabbitmq-server --no-pagerExpected output:
● rabbitmq-server.service - RabbitMQ broker
Loaded: loaded (/lib/systemd/system/rabbitmq-server.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-04-16 10:00:00 UTC; 10s ago
Main PID: 1234 (beam.smp)Confirm node health with the diagnostics tool:
sudo rabbitmq-diagnostics -q status | head -n 20You should see the node name (typically rabbit@hostname), the product version (RabbitMQ 4.x.x), and the Erlang/OTP release.
Step 5: Enable the Management Plugin
The management plugin is the primary way most teams interact with RabbitMQ. It ships with the broker and provides:
- A browser UI at
http://your-server:15672 - An HTTP REST API at
http://your-server:15672/api/ - A command-line client
rabbitmqadmin - Metrics for Prometheus (via
rabbitmq_prometheus, typically port 15692)
sudo rabbitmq-plugins enable rabbitmq_managementExpected output:
Enabling plugins on node rabbit@hostname:
rabbitmq_management
The following plugins have been configured:
rabbitmq_management
rabbitmq_management_agent
rabbitmq_web_dispatch
started 3 plugins.Confirm port 15672 is listening:
sudo ss -ltnp | grep -E "5672|15672"You should see 5672 (AMQP) and 15672 (management) both bound.
Open the UI in your browser at http://your-server-ip:15672. You will be prompted for credentials -- do not log in with the default guest / guest. The next step replaces it.
Step 6: Write rabbitmq.conf
Modern RabbitMQ (3.7+) uses a simple ini-style config at /etc/rabbitmq/rabbitmq.conf. Create it with a production-sane baseline:
sudo tee /etc/rabbitmq/rabbitmq.conf > /dev/null <<'EOF'
---- Listeners ----
listeners.tcp.default = 5672
management.tcp.port = 15672Only allow guest from localhost (or disable entirely below).
loopback_users.guest = trueIf you want to disable loopback_users entirely so you can log in
remotely with a non-guest admin you create below, leave this empty:
loopback_users = none
---- Disk and memory thresholds ----
Refuse to accept publishes when free disk falls below 2 GB.
disk_free_limit.absolute = 2GBApply flow control (back-pressure) when RabbitMQ is using more than
40% of system RAM. This is the default; tune it for your host.
vm_memory_high_watermark.relative = 0.4---- Log level ----
log.console = true
log.console.level = info
log.file.level = info---- Default vhost and user ----
We will override the default 'guest' by creating a real admin below.
default_vhost = /
default_user = guest
default_pass = guest---- Cluster name (shown in the UI, useful once clustered) ----
cluster_name = rmq-primary---- Heartbeat and frame size ----
heartbeat = 60
frame_max = 131072
channel_max = 2047
EOFThe key production settings:
listeners.tcp.default = 5672-- the AMQP 0-9-1/1.0 listener.loopback_users.guest = true-- the defaultguestuser can only log in from127.0.0.1, never from the network. This is the default in modern RabbitMQ and the right setting for production.disk_free_limit.absolute = 2GB-- RabbitMQ blocks publishes when free disk drops below this value. If you set it too low you risk the node crashing after the disk fills.vm_memory_high_watermark.relative = 0.4-- at 40% of system RAM, RabbitMQ stops accepting publishes and flushes queues to disk. Raise to0.6only if the broker is dedicated to this workload.heartbeat = 60-- 60-second heartbeats detect dead clients quickly without too much chatter.
loopback_users.guest = true to the commented line loopback_users = none. Either is fine -- keeping guest loopback-only is simpler.Restart to apply:
sudo systemctl restart rabbitmq-serverStep 7: Create Users, Vhosts, and Permissions
The rabbitmqctl CLI is how you manage users, vhosts, and permissions. Never ship production with the default guest user reachable from the network.
Create an administrator
sudo rabbitmqctl add_user admin 'ChangeMe-StrongPass-2026!'
sudo rabbitmqctl set_user_tags admin administratorThe administrator tag grants full management UI access across all vhosts.
Create an application vhost
Vhosts are logical namespaces. Every queue, exchange, and binding lives in one vhost. Use them to isolate environments (staging vs prod) or tenants.
sudo rabbitmqctl add_vhost /appCreate an application user scoped to /app
Never use the administrator credentials from application code. Create a service account with least-privilege permissions:
sudo rabbitmqctl add_user app_svc 'app-svc-password-xyz'
sudo rabbitmqctl set_user_tags app_svc noneGrant configure/write/read permissions on the /app vhost. The three arguments are regex patterns matching resource names:
sudo rabbitmqctl set_permissions -p /app app_svc '.' '.' '.*'If you want read-only access (a consumer that should never declare queues), scope it:
sudo rabbitmqctl set_permissions -p /app read_only_user '' '' '.*'Delete the default guest user
Once your admin works, remove guest entirely:
sudo rabbitmqctl delete_user guestVerify
sudo rabbitmqctl list_users
sudo rabbitmqctl list_vhosts
sudo rabbitmqctl list_permissions -p /appExpected output:
Listing users ... user tags admin [administrator] app_svc []Listing vhosts ... name / /app
Listing permissions for vhost "/app" ... user configure write read app_svc . . .*
Now log into the management UI at http://your-server-ip:15672 with admin and your strong password.
Step 8: Exchanges, Queues, and Bindings
With a user, vhost, and permissions in place you can declare the core AMQP primitives. There are four exchange types:
| Exchange Type | Routing Behaviour | Typical Use |
|---|---|---|
direct | Routes to queues whose binding key equals the routing key | Point-to-point work distribution |
topic | Routing key is a dotted string; bindings use wildcards * and # | Pub/sub with hierarchical keys (order.us.paid) |
fanout | Routes to all bound queues; routing key ignored | Broadcasts, cache invalidation |
headers | Routes on message header matches instead of routing key | Rarely used; covered for completeness |
Declare an exchange, queue, and binding with rabbitmqadmin
The management plugin ships with a Python CLI called rabbitmqadmin. Download it:
sudo curl -o /usr/local/bin/rabbitmqadmin http://localhost:15672/cli/rabbitmqadmin
sudo chmod +x /usr/local/bin/rabbitmqadminDeclare a topic exchange called orders:
rabbitmqadmin -u admin -p 'ChangeMe-StrongPass-2026!' -V /app \
declare exchange name=orders type=topic durable=trueDeclare a durable quorum queue called orders.paid.q:
rabbitmqadmin -u admin -p 'ChangeMe-StrongPass-2026!' -V /app \
declare queue name=orders.paid.q durable=true \
arguments='{"x-queue-type":"quorum"}'Bind the queue to the exchange with a topic pattern that matches order.*.paid:
rabbitmqadmin -u admin -p 'ChangeMe-StrongPass-2026!' -V /app \
declare binding source=orders destination=orders.paid.q routing_key='order.*.paid'Publish a test message:
rabbitmqadmin -u admin -p 'ChangeMe-StrongPass-2026!' -V /app \
publish exchange=orders routing_key='order.us.paid' payload='{"id":42,"amount":9.99}'Get it back:
rabbitmqadmin -u admin -p 'ChangeMe-StrongPass-2026!' -V /app \
get queue=orders.paid.q count=1You should see the JSON payload echoed back with a routing_key of order.us.paid.
Step 9: Quorum Queues and Streams
RabbitMQ 4.x has three queue types. Pick the right one -- this is the single most important architectural decision on the broker.
Quorum Queues (the default for HA)
Quorum queues use the Raft consensus algorithm for replication. They replace the deprecated "classic mirrored queues" (which were removed in RabbitMQ 4.0 because of well-known data-loss modes). Quorum queues are:
- Durable by default -- every message is persisted to disk before acknowledgment.
- Replicated across a configurable number of cluster nodes (typically 3 or 5).
- Safe under network partitions -- the majority wins; the minority refuses writes.
- Slightly slower than classic queues on raw throughput, but dramatically safer.
rabbitmqadmin -u admin -p '...' -V /app declare queue \
name=jobs.q durable=true \
arguments='{"x-queue-type":"quorum","x-quorum-initial-group-size":3}'Use quorum queues for any workload where losing a message is unacceptable: payments, orders, webhooks, audit logs.
Streams (append-only logs)
Streams are a newer queue type designed for high-throughput fan-out and replay, similar to Kafka topics. They:
- Store messages in an append-only log on disk with no per-message acks.
- Allow many consumers to read from different offsets independently.
- Support replay from an arbitrary offset -- perfect for "replay yesterday's events into a new service."
- Speak both AMQP 0-9-1 and the dedicated RabbitMQ Streams protocol on port 5552 for the highest throughput.
sudo rabbitmq-plugins enable rabbitmq_stream rabbitmq_stream_managementDeclare a stream:
rabbitmqadmin -u admin -p '...' -V /app declare queue \
name=events.stream durable=true \
arguments='{"x-queue-type":"stream","x-max-length-bytes":10000000000}'That creates a 10 GB rolling stream. When it fills up, older segments are deleted.
Use streams for: log aggregation, event sourcing, metrics fan-out, IoT telemetry, change-data-capture. If Kafka would be the right tool but you already run RabbitMQ, streams are usually a good substitute -- see also how to install Kafka on Ubuntu for a side-by-side comparison.
Classic queues (legacy)
Classic queues still exist for single-node, non-replicated use cases where you want the lowest possible latency and do not need HA. They are fine for lossy workloads like metrics scrapes or SMS rate-limit buckets. Do not use them for anything a business depends on in a cluster -- use quorum queues instead.
Step 10: Federation and Shovel
For cross-region or cross-cluster replication, RabbitMQ provides two plugins:
Federation
The federation plugin links exchanges or queues between independent clusters. A downstream exchange transparently subscribes to an upstream exchange and receives messages as if published locally. Federation tolerates network partitions gracefully because it treats the upstream as a normal AMQP client.
Enable it:
sudo rabbitmq-plugins enable rabbitmq_federation rabbitmq_federation_managementTypical use: one "primary" cluster in Frankfurt, a "DR" cluster in Virginia, and you federate the orders exchange so every order published anywhere ends up in both regions' queues.
Shovel
The shovel plugin moves messages from a source queue/exchange to a destination, either in the same broker or a different one. Shovels are a point-to-point, directional mechanism -- ideal for:
- One-time data migrations between brokers.
- Bridging RabbitMQ to an external AMQP 1.0 system (Azure Service Bus, Qpid).
- Archival patterns that pull from a live queue into a long-retention stream.
sudo rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_managementDeclare a dynamic shovel via the management UI or rabbitmqctl set_parameter shovel ....
Rule of thumb: use federation for ongoing replication across clusters; use shovel for migrations, bridging, and one-off moves.
Step 11: Enable TLS
Never run production RabbitMQ on plain TCP across the internet. The broker supports TLS on all listeners.
Generate or obtain certificates
For a real domain, use Let's Encrypt:
sudo apt install -y certbot
sudo certbot certonly --standalone -d rabbit.yourdomain.comLet's Encrypt writes certs to /etc/letsencrypt/live/rabbit.yourdomain.com/.
RabbitMQ needs read access to those files. The rabbitmq user must be in a group that can read the privkey.pem. The simplest approach is to copy the certs into RabbitMQ's config directory:
sudo mkdir -p /etc/rabbitmq/tls
sudo cp /etc/letsencrypt/live/rabbit.yourdomain.com/fullchain.pem /etc/rabbitmq/tls/
sudo cp /etc/letsencrypt/live/rabbit.yourdomain.com/privkey.pem /etc/rabbitmq/tls/
sudo chown -R rabbitmq:rabbitmq /etc/rabbitmq/tls
sudo chmod 600 /etc/rabbitmq/tls/privkey.pemAdd TLS listeners to rabbitmq.conf
Edit /etc/rabbitmq/rabbitmq.conf and append:
## ---- TLS listeners ----
listeners.ssl.default = 5671
ssl_options.cacertfile = /etc/rabbitmq/tls/fullchain.pem
ssl_options.certfile = /etc/rabbitmq/tls/fullchain.pem
ssl_options.keyfile = /etc/rabbitmq/tls/privkey.pem
ssl_options.verify = verify_none
ssl_options.fail_if_no_peer_cert = false
ssl_options.versions.1 = tlsv1.3
ssl_options.versions.2 = tlsv1.2TLS management UI on 15671
management.ssl.port = 15671
management.ssl.cacertfile = /etc/rabbitmq/tls/fullchain.pem
management.ssl.certfile = /etc/rabbitmq/tls/fullchain.pem
management.ssl.keyfile = /etc/rabbitmq/tls/privkey.pemOptionally disable the plain-text listener so clients must use TLS:
listeners.tcp = noneRestart:
sudo systemctl restart rabbitmq-serverVerify the TLS listener:
openssl s_client -connect rabbit.yourdomain.com:5671 -servername rabbit.yourdomain.com < /dev/nullYou should see the Let's Encrypt certificate chain and Verify return code: 0 (ok).
Set up a cron job (or certbot renew --post-hook) to re-copy the cert after each renewal and reload RabbitMQ:
sudo tee /etc/letsencrypt/renewal-hooks/post/rabbitmq.sh > /dev/null <<'EOF'
#!/bin/bash
cp /etc/letsencrypt/live/rabbit.yourdomain.com/fullchain.pem /etc/rabbitmq/tls/
cp /etc/letsencrypt/live/rabbit.yourdomain.com/privkey.pem /etc/rabbitmq/tls/
chown rabbitmq:rabbitmq /etc/rabbitmq/tls/*
chmod 600 /etc/rabbitmq/tls/privkey.pem
systemctl reload rabbitmq-server
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/rabbitmq.shStep 12: HA Clustering
A single node is a single point of failure. For real production, run three nodes (the minimum for Raft quorum) in the same datacenter region.
1. Provision three nodes with the same Erlang cookie
RabbitMQ nodes authenticate to each other via a shared secret at /var/lib/rabbitmq/.erlang.cookie. On node 1, read it:
sudo cat /var/lib/rabbitmq/.erlang.cookieOn nodes 2 and 3, stop the broker and overwrite the cookie with the same value:
sudo systemctl stop rabbitmq-server
echo -n 'PASTE_THE_COOKIE_FROM_NODE1_HERE' | sudo tee /var/lib/rabbitmq/.erlang.cookie > /dev/null
sudo chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie
sudo chmod 600 /var/lib/rabbitmq/.erlang.cookie
sudo systemctl start rabbitmq-server2. Make node names resolvable
Every node must be reachable by hostname. The simplest approach is to add entries to /etc/hosts on each node:
sudo tee -a /etc/hosts <<EOF
10.0.0.11 rmq1
10.0.0.12 rmq2
10.0.0.13 rmq3
EOFSet each node's hostname to match (rmq1, rmq2, rmq3) and reboot.
3. Join nodes 2 and 3 to node 1
On node 2:
sudo rabbitmqctl stop_app
sudo rabbitmqctl reset
sudo rabbitmqctl join_cluster rabbit@rmq1
sudo rabbitmqctl start_appRepeat on node 3, joining the same rabbit@rmq1.
Verify from any node:
sudo rabbitmqctl cluster_statusYou should see all three nodes listed as Running Nodes with an identical cluster name.
4. Quorum queue replica count
For a 3-node cluster, set x-quorum-initial-group-size=3 on all your HA queues so every queue has a replica on every node. For a 5-node cluster, use 3 or 5 depending on how much replication overhead you want to pay.
5. Load balancer in front
Point applications at a single TCP load balancer (HAProxy, Nginx stream, or a cloud LB) that fronts all three nodes on port 5672/5671. Applications should not hardcode a single node.
Example minimal HAProxy config:
frontend amqp bind *:5672 mode tcp default_backend rmq
backend rmq mode tcp balance roundrobin option tcp-check server rmq1 10.0.0.11:5672 check inter 5s server rmq2 10.0.0.12:5672 check inter 5s server rmq3 10.0.0.13:5672 check inter 5s
6. Do not stretch clusters across regions
The Mnesia metadata layer and the Raft log in quorum queues are latency-sensitive. Keep cluster members within the same region (< 10 ms RTT). For cross-region replication, use federation between two independent clusters as described in Step 10.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
rabbitmqctl says "unable to connect to epmd" | Broker not running or epmd conflict | sudo systemctl status rabbitmq-server, then sudo journalctl -u rabbitmq-server -n 100 --no-pager |
| Cannot log into management UI with admin user | loopback_users.guest = true blocking non-guest user, or wrong password | Reset with sudo rabbitmqctl change_password admin 'newpass' |
| Publishes hang indefinitely | Memory or disk alarm active | sudo rabbitmqctl status</td><td>grep alarm<code> -- if there is a </code>memory<code> or </code>disk alarm, free RAM/disk or raise the watermark |
Queue type error: x-queue-type arg not supported | Feature flag not enabled | sudo rabbitmqctl enable_feature_flag all |
| Cluster join fails with "cookie mismatch" | .erlang.cookie differs between nodes | Copy cookie from primary to all nodes, set perms 600, restart |
| Management UI 503 after plugin enable | Plugin conflict or port 15672 already used | sudo ss -ltnp</td><td>grep 15672<code>, disable conflicting service, </code>sudo rabbitmq-plugins disable then re-enable |
High CPU on beam.smp with few connections | Heartbeat too aggressive or log at debug level | Raise heartbeat to 60 in rabbitmq.conf, set log.console.level = info |
| Messages stuck in "unacked" state | Consumer crashed without acking | Restart consumer; it will redeliver. Add consumer_timeout in rabbitmq.conf to auto-requeue |
Key log locations
- Main log:
/var/log/rabbitmq/[email protected] - Systemd journal:
sudo journalctl -u rabbitmq-server -f - Upgrade log:
/var/log/rabbitmq/rabbit@hostname_upgrade.log
FAQ
What ports does RabbitMQ use?
| Port | Protocol / Purpose |
|---|---|
| 5672 | AMQP 0-9-1 and AMQP 1.0 (plain) |
| 5671 | AMQP over TLS |
| 15672 | Management UI + HTTP API (plain) |
| 15671 | Management UI + HTTP API (TLS) |
| 15692 | Prometheus metrics (plugin) |
| 25672 | Inter-node Erlang distribution (clustering) |
| 4369 | epmd (Erlang port mapper daemon) |
| 61613 / 61614 | STOMP (plain / TLS, plugin) |
| 1883 / 8883 | MQTT (plain / TLS, plugin) |
| 5552 | RabbitMQ Streams binary protocol |
Should I use classic mirrored queues or quorum queues?
Use quorum queues. Classic mirrored queues were removed in RabbitMQ 4.0 because they had well-known failure modes (split-brain, message loss during partition healing). Quorum queues use the Raft consensus algorithm, are the modern replicated queue type, and are what the RabbitMQ team actively invests in. For append-only log workloads, use streams.
How much RAM does RabbitMQ need?
A minimal single-node broker runs on 1 GB RAM. For production we recommend at least 4 GB so that the default vm_memory_high_watermark.relative = 0.4 gives RabbitMQ roughly 1.6 GB before it triggers flow control. Workloads with many long queues, large messages, or many connections need more -- plan for 8-16 GB on a busy broker.
How does RabbitMQ compare to Kafka, NATS, and Redis Streams?
- RabbitMQ excels at smart routing (topic/direct/headers exchanges), per-message acks, and multi-protocol support (AMQP, MQTT, STOMP). Quorum queues give you durable replication; streams give you Kafka-style append-only logs.
- Apache Kafka is a partitioned commit log optimized for very high throughput and long retention. See how to install Kafka on Ubuntu.
- NATS / NATS JetStream is lighter weight than RabbitMQ and Kafka, with very low latency and simple subject-based routing. See how to install NATS on Ubuntu.
- Redis Streams / Pub-Sub is embedded in the Redis in-memory data store, good for low-latency cache-adjacent pipelines but not designed for durable long-retention queues. See how to install Redis on Ubuntu.
Why self-host RabbitMQ instead of using CloudAMQP?
Self-hosting on a CloudCore VPS is typically 3-10x cheaper at the same throughput, keeps sensitive message payloads on infrastructure you control, avoids per-connection pricing, lets you tune Erlang VM flags, enables any plugin you need, and removes the multi-tenant noisy-neighbour risk of shared AMQP SaaS. The operational overhead is modest -- once you have run through this guide, day-to-day maintenance is unattended-upgrades plus watching the Prometheus metrics.
Can I cluster RabbitMQ across regions?
No -- do not stretch a single cluster across regions. The Mnesia metadata layer and the Raft consensus in quorum queues require sub-10ms latency between nodes. Instead, run one cluster per region and replicate between them with the federation or shovel plugin (see Step 10).
How do I back up RabbitMQ?
Two parts:
rabbitmqctl export_definitions /tmp/defs.json. Store in git./var/lib/rabbitmq/mnesia/. Stop the node (or snapshot at the filesystem/block level), tar the directory, and copy elsewhere. For clusters, restore from the definitions plus any one node's data.For most workloads the definitions export is the only backup that matters -- messages are ephemeral by design.
Next Steps
Now that RabbitMQ is running, here is where to go next:
- Hook up Prometheus metrics -- enable
rabbitmq_prometheusand scrapehttp://node:15692/metricsfrom your Prometheus server. The RabbitMQ team ships an excellent Grafana dashboard (ID 10991). - Install a companion broker for comparison -- if your workload is high-throughput append-only event streaming, also evaluate Kafka or NATS.
- Add Redis for cache and short-lived queues -- many production stacks run RabbitMQ + Redis side-by-side. See how to install Redis on Ubuntu.
- Read the official docs -- the RabbitMQ documentation is exceptionally good, especially the queues and streams sections. Bookmark it.
- Set up dead-letter exchanges -- any production queue should route failed messages to a DLX so you can inspect and replay them. Add
x-dead-letter-exchangeandx-dead-letter-routing-keyto queue declarations. - Tune your client libraries -- enable publisher confirms, consumer acks, and set a reasonable prefetch count (typically 10-100). These four settings, not broker tuning, are responsible for 90% of real-world RabbitMQ performance problems.
Ready to Deploy?>
CloudCore Starter gives you enough CPU, RAM, and NVMe to run a single-node RabbitMQ broker plus your application for EUR 7.99/month. For a 3-node HA cluster, provision three instances in the same region and follow Step 12.>
- Ubuntu 24.04 LTS pre-installed
- Full root access, no restrictions on plugins or ports
- 1 Gbps unmetered bandwidth
- Hourly or monthly billing>
Launch your CloudCore VPS now.