RabbitMQ for IoT

For Internet of Things (IoT) projects that are a lot of different ways that the sensors, devices and client interfaces can be connected together. For many projects using simple MQTT (Message Queue Telemetry Transport) is all that you need. However if you’re trying to merge and build IoT projects that use both MQTT and AMQP (Advanced Message Queue Protocol) or require a REST API then you should take a look at RabbitMQ.

RabbitMQ is an open source middleware solution that natively uses AMQP communications but it has a good selection of plug-ins to support features like: MQTT, MQTT Web Sockets, HTTP REST API and server-to-server communications.


In this blog we will setting up a RabbitMQ server, and we will look at some of the differences between MQTT and AMQP messaging. Finally an example of an Anduino MQTT message will be presented as both an MQTT and an AMQP item in a Node-Red dashboard.

Getting Started

RabbitMQ can be installed on Window, Linux, MacOS systems and there are also some cloud based offerings. For small systems lower end hardware like a Raspberry Pi can be used.  For complete RabbitMQ installation instructions see: https://www.rabbitmq.com/download.html . To install and run RabbitMQ on a Ubuntu system enter:

sudo apt-get update
sudo apt-get install rabbitmq-server
sudo service rabbitmq-server start

The next step is to add some plug-ins. For my project I loaded the MQTT and Web Administration plug-ins:

sudo rabbitmq-plugins enable rabbitmq_mqtt
sudo rabbitmq-plugins enable rabbitmq_management

The rabbitmqctl command line tool allows you to configure and review the RabbitMQ server. To add a user admin1,  with password admin1, that has config, write and read rights for management and administrator access, enter:

sudo rabbitmqctl add_user admin1 admin1
sudo rabbitmqctl set_permissions -p / admin1 ".*" ".*" ".*"
sudo rabbitmqctl set_user_tags admin1 management administrator

After you’ve defined an administrative user the RabbitMQ web management plug-in can be accessed by: http://ip_address:15672 .


The RabbitMQ Web Management tool offers an overview of the present system load, connections, exchanges and queues. 

The RabbitMQ Web Management tool is excellent for small manual changes, if however you are looking a doing a large number of additions or changes then, rabbitmqadmin, the command line management tool can be used. This tool is  installed by:

# Get the cli and make it available to use.
sudo chmod +x rabbitmqadmin

Comparing MQTT and AMQP

It’s useful to comment about some of the differences between MQTT (Message Queue Telemetry Transport) and AMQP (Advanced Message Queueing Protocol) .

MQTT is a light weight publish-subscribe-based messaging protocol that works well with lower end hardware and limited bandwidth. For Arduino type applications where you only need to pass some sensor data MQTT is an excellent fit.

AMQP has more overhead than MQTT, because it is a more advanced protocol that includes message orientation, queuing, routing, reliability and security. Presently there are no mainstream AMQP Arduino libraries, but numerous programming options for Raspberry Pi, Linux, Windows and MacOS systems exist.  An AMQP IoT example would be to send sensor failures and alarms to dedicated maintenance and alarm queues.

MQTT and AMQP Queues

One of the biggest differences in queues is that MQTT queues are designed to show you the last available message, where as AMQP will store multiple messages in a queue.

A published MQTT message contains a message body, a retain flag and a quality of service (QoS) value.

An AMQP message can be published with added properties such as: time stamp, type of message and expiration information. AMQP messages also support the addition of custom header values. Below is a Python publish example that defines the message type to be “Pi Sensor”, and custom headers are include for status and alarm state.

#!/usr/bin/env python
import pika

node = ""
user = "pete"
pwd = "pete"

# Connect to a remote AMQP server with a username/password
credentials = pika.PlainCredentials(user, pwd)
connection = pika.BlockingConnection(pika.ConnectionParameters(node,
        5672, '/', credentials))                                    
channel = connection.channel()

# Create a queue if it doesn't already exist

# Define the properties and publish a message
props = pika.BasicProperties(
    headers= {'status': 'Good Quality',"alarm":"HI"},
    type ="Pi Sensor")
    routing_key='Rasp_1',body='99.5', properties = props)


For this example the Rasp_1 queue can be examined using the Queue->Get Message option in the Web Management Interface. 


RabbitMQ Messaging

There are a variety of ways that AMQP messages can be published and subscribed to. The simplest way is to create a queue and then messages can be published and subscribed to from that queue.

rabbitmq_layoutTo help with the distribution and filtering of messages AMQP supports a number of different exchange types. Messages in an exchange use bindings based on a routing key to link them to a queue. 

The main types of exchanges are: direct, fanout, headers and topic. An IoT example of a direct exchange would be if a group of Raspberry Pi sensor values are going into a “Rasp Pi Sensor” exchange. When the Rasp Pi publishes a sensor result to the exchange the message also includes a routing key to link the message to the correct queue.


An IoT example of a fanout exchange would be with critical sensor failures. The sensor failure message is sent to Bill’s and Sam’s work or task queue and the All Maintenance point queue at the same time.


Connecting MQTT

After the MQTT plug-in is installed RabbitMQ can act like a standalone MQTT broker. MQTT data can also be made available through an AMQP subscription by binding the MQTT exchange to a RabbitMQ queue.

For an MQTT project any ESP8266 supported Arduino hardware can be used. There are a number of MQTT Arduino libraries that are available. For this project I used the PubSubClient that can be installed using the Arduino Library Manager.

As a test project I used at low cost MQ-2 Combustible Gas Sensor ($3) that measures a combination of LPG, Alcohol, Propane, Hydrogen, CO and even methane. Note to fully use this sensor some calibration is required. On the MQ-2 sensor the analog signal is connected to Arduino pin A0 and the analogRead(thePin) function is used to read the sensor value.


Below is some example Arduino code required to read the MQ2 gas sensor and publish it to the RabbitMQ MQTT broker with a topic name of : mq2_mqtt.

 Basic ESP8266 MQTT publish client example
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.
const char* ssid = "your_ssid";
const char* password = "your_password";
const char* mqtt_server = ""; 
const char* mqtt_user = "admin1";
const char* mqtt_pass= "admin1";

const int mq2pin = A0; //the MQ2 analog input pin

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  // Connecting to a WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
  Serial.println("WiFi connected");
  Serial.println("IP address: ");

void reconnect() {
  // Loop until we're reconnected
  Serial.println("In reconnect...");
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("Arduino_Gas", mqtt_user, mqtt_pass)) {
    } else {
      Serial.print("failed, rc=");
      Serial.println(" try again in 5 seconds");

void setup() {
  client.setServer(mqtt_server, 1883);

void loop() {
  char msg[8];
  if (!client.connected()) {

  client.publish("mq2_mqtt", msg);
  Serial.print("MQ2 gas value:");


Once the MQTT value is published any MQTT client can subscribe to it.  Below is a Python MQTT subscribe example.

# mqtt_sub.py - Python MQTT subscribe example 
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
    print("Connected to broker")
def on_message(client, userdata, message):
    print ("Message received: "  + message.payload)

client = mqtt.Client()
client.username_pw_set("admin1", password='admin1')
client.connect("", 1883) 

client.on_connect = on_connect       #attach function to callback
client.on_message = on_message       #attach function to callback

client.loop_forever()                 #start the loop

Read MQTT Messages Using AMQP

MQTT clients can subscribe to MQTT messages directly or it’s possible to configure RabbitMQ to have the MQTT data accessible as AMQP. The routing of MQTT messages to AMQP queues is done using the direct exchange method.


To configure RabbitMQ to forward MQTT the following steps are done:

  1. Create a new RabbitMQ Queue – For an IoT project this would typically be a 1-to-1 mapping of the MQTT topic to a queue name.
  2. Create a binding between the MQTT Exchange and the Queue – by default all the MQTT topic go into the amq.topic exchange. For MQTT items in this exchange a binding, typically the MQTT topic name, is used as the routing key to the AMQP queue.

These steps can be done in a number of ways : manually, in the RabbitMQ config file, using the rabbitmqadmin command line tool or via a program. Because I was doing this for multiple signals I used rabbitmqadmin tool, and the syntax is:

./rabbitmqadmin declare queue name=mq2_amqp durable=true
./rabbitmqadmin declare binding source=amq.topic destination_type=queue destination=mq2_amqp routing_key=mq2_mqtt

The RabbitMQ Web Admin can be used to verify the exchange to queue binding.



The CLI tool can also be used to see if there are any values in the queue:


Node-Red Dashboard

Node-Red is a visual programming environment that allows users to create applications by dragging and dropping nodes on the screen. Logic flows are then created by connecting the different nodes together.

Node-Red has been preinstalled on Raspbian Jesse since the November 2015. Node-Red can also be installed on Windows, Linux and OSX.  To install and run Node-Red on your specific system see https://nodered.org/docs/getting-started/installation.

To install the AMQP components, select the Manage palette option from the right side of the menu bar. Then search for “AMQP” and install node-red-contrib-amqp. If your installation of Node-Red does not have dashboards installed, search for: node-red-dashboard.


For our Node-Red MQTT and AMQP example we will use a mqtt and a amqp node from the input palette group, and two gauge nodes from the dashboard group.  The complete Node-Red logic for this is done in only 4 nodes!


Nodes are added by dragging and dropped them into the center Flow sheet. Logic is created by making connection wires between inputs and output of a node. After the logic is laid out, double click on each of the nodes to configure their specific properties. You will need to specify the MQTT and AMQP definitions of your RabbitMQ IP address,user rights, MQTT topic and AMQP queue name. You will also need to double click on the gauge nodes to configure the look-and-feel of the web dashboard.

After the logic is complete, hit the Deploy button on the right side of the menu bar to run the logic.  The Node-Red dashboard user interface is accessed by: http://ipaddress:1880/ui. 

For my project I used a number of different MQ sensors and inputs. Below is a picture of Node-Red web dashboard that we created with the same MQTT value being shown natively and as a AMQP queued value.


Final Comments

I found that RabbitMQ was easy to install and the Web Administration plug-in along with the rabbitmqadmin command line tool made it very easy to maintain. 

If you’re just looking to show sensor values then a basic MQTT broker might be all you need. However if you’re looking at some future applications like alarm, maintenance or task lists then AMQP exchanges and queue make RabbitMQ an interesting option.

More on RabbitMQ:

RabbitMQ REST API – remote interfacing (Javascript and Python examples)

RabbitMQ connections with Excel

27 thoughts on “RabbitMQ for IoT

  1. Excellent tutorial! This was an enormous help. I just wanted to mention that “sudo rabbitmq-plugins enable rabbitmq-management” should be “sudo rabbitmq-plugins enable rabbitmq_management.
    slight typo but everything else was 100% on point. Thank you


  2. Very nice tutorial ! I have one question though.

    I am looking at the this text of your’s: “MQTT clients can subscribe to MQTT messages directly or it’s possible to configure RabbitMQ to have the MQTT data accessible as AMQP. The routing of MQTT messages to AMQP queues is done using the direct exchange method.”

    I did bind a queue to the mqtt exchange in my rabbitmq node. All the messages being published by the IOT devices are now being received on this queue. But these messages aren’t persistent on the queue. They are getting lost from the queue as soon as I restart rabbitmq. Do you know a way to make these messages as persistent? The arduino library does not have a delivery mode flag, so the publisher can’t set this. And on the RabbitMQ level, this property can’t be set explicitly on the queue. Can you please advice?


    1. Hi Anurag,

      Did you enabled the MQTT retain settings in the MQTT plugin to RabbitMQ ? Take a look at the “Retained Message Stores” section (https://www.rabbitmq.com/mqtt.html#retained).

      Also when you do a publish you’ll need to enable this. You can quickly tests this with the Mosquitto pub test tool:

      mosquitto_pub [-h host] [-q qos] [-r] | -m message} -t topic

      where -r : message should be retained.


      1. Thanks Pete for the quick reply !

        Yes, I tried the retained setting. But reading the documentation about it, looks like it’s only for the last message published by the producer and when a consumer comes online, it gets that last message. Suppose I send 10 messages with the retained setting, only the last one is received by the new consumers.

        I think thats by MQTT design, where a new consumer does not care about all the previous messages as the last retained message provides the state of the producer or the first command for the consumer.

        In RabbitMQ amqp world, there is a property “delivery_mode” which is to be set by the producer when sending each message. This property, when set to “2”, makes the message persistent on the queues and lets it survive the broker restart. There is no other way I know of which can make a message persistent.

        I am not sure if MQTT also supports this property. At least, I could not find it in the PubSubClient MQTT library. If MQTT can’t send this property, then I do not see a way for the broker to persist messages on an amqp queue. Do you know or think of a way to achieve this?


      2. Hi Anurag,
        I’ve found a similar limitation in MQTT, and I believe this is why you’ll often see a database included in a MQTT solution. The database will store the history and MQTT does the real time info.

        If you use AMQP in RabbitMQ it will store a defined number of historical values. However I found this can be confusing when you have multiple AMQP subscribers, because by default you get the oldest value first, and not the newest value (there are workarounds for this). A subscriber can delete a message after it is read, but this deletes the message for ALL subscribers, not ideal.

        Each system has it’s pro’s and con’s. You might need to review your needs and look at a solution that meets all your needs.

        If you need to retain old values I highly recommend InfluxDB. The only issue I found is that the Arduino library for it can write and does not read at this point. Python and Node-Red are solid, and you can request value historical, like: ‘NOW-10 minutes’.

        Hope this helps. Pete


      3. Hi Pete, Yes your comments help.

        Good to know that you also see that limitation. Also, like you mentioned, deletion of data can cause deletion for all; that I did not know, so that’s a good learning for me. I will test it to understand the behavior.

        I think you guessed my use case correctly. Just describing it for the discussion context.

        My devices are talking to each other using RabbitMQ MQTT broker for real time commands and status. In the next phase, I want to insert some data like temperature, humidity etc. into a database and develop some analytics and charts around it. I have a DB Connector app for that purpose which can subscribe to both MQTT and AMQP. Now, as you mentioned, MQTT broker has the limited amount of data stored. In case my DB connector app is down for longer than the MQTT broker message retention period, I would lose messages. Hence, I created an AMQP subscription to the amq.topic topic and started getting all messages in a queue. Now the DB connector reads from the amqp queue. And even if my DB connector app is down, say, for a week, I have all my messages sitting in the queue waiting for the DB connector to come back.
        But since the NodeMCU MQTT publisher is unable to send the amqp field “delivery mode”, these messages are non-persistent and won’t survive a rabbitmq cluster crash, and will be lost assuming, they were waiting for DB connector to consume them.

        So, when you say you often see a database included in the MQTT solution, generally speaking, does the IOT devices send data directly to the databases? Or those solutions too follow the type of approach I am following, as mentioned above? In the influx DB mention by you looks like you are talking about sending data directly from the Arduino device to the database. Also, if low resources IOT devices like Arduino, and not PI, send data to DBs, do you know if those DB calls are heavy?

        Thanks again for your replies and interest in my queries. I am new to IOT hence do not know about such details like DB calls and call load etc.


      4. Hi Anurag,
        I spent a lot of time doing industrial process control, and we always faced the issue of how much redundancy, features and history is the customer willing to pay for. All the servers in the system can be made redundant, but as the redundancy increases so does the complexity and cost.

        MQTT, Redis and AMQP are great for simpler IoT projects but you’ll never see them in chemical or power plant where high levels of redundancy and history are needed.

        If you are looking at some simple ways to “harden” your system I might consider looking at mirroring your RabbitMQ servers to save data on crashes, and adding UPS. Saving history to mirrored database servers will ensure retention of long term history.

        Also in the Arduino code it’s possible to monitor the server status and If the server is down you could retain the history in the Arduino until the server(s) are back online.



      5. Hey Pete,

        Great to know I am talking to someone who has real life experience in IOT; unlike me who is just starting !

        You are right about redundancy. I am also mirroring my RabbitMQ cluster, its only that I do not have message persistence. But it would only come into use if the whole RabbitMQ cluster goes down along with DB Connector. Such scenario shall only present itself in case of a DR type event; in case of which, some data loss is acceptable. But for now, in a non-DR, failover scenario, I think we can live with this shortfall by implementing HA/redundancy and proactive monitoring.

        I also liked your thought about retaining the events in Arduino/IOT device in case of server going down.

        Another question please 🙂 , you mentioned MQTT/AMQP/Redis aren’t used in huge implementations. What are the alternative technologies/methodologies which are used in such high scale implementations so that the IOT/Sensor/End Point devices can talk to each other and backend servers? Is Apache Kafka a good guess (though it does not support MQTT/AMQP)? You do not have to describe them in great details. You can just name some you think are the best and I will try to read about them on my own.

        Sorry, if I am deviating away from your current article. But just got curious about the big real time applications; such as what you have mentioned. And Thanks again for your quick and informative responses !


      6. Hi Anurag,
        I can’t speak for all areas because there are so many variations.

        People’s view of IoT, and especially IIoT (industrial IoT) will vary based on the user and industry. Most industrial control systems will use a control protocol like OPC, IEC61850, TASE.2 or IEC 104 and proprietary data systems. Then the IoT for executives and consumers will be a web interface on top of the proprietary solution. The big players are Siemens, Allen-Bradley, Emerson and ABB.

        Smaller consumer level non-critical processes are a perfect MQTT, AMQP, REDIS solution. Database historical storage could be offerings like MySQL, MongoDB or MS Sql server.

        Amazon Web Services is by far the largest supplier of cloud services with a huge offering of solutions. DynamoDB is an excellent IoT storage mechanism.

        The very big IoT solutions in my region use Google Big Data.

        This is what I’m seeing in my region, yours may differ.



  3. Hi Pete,

    Honestly, I never heard of the protocols you mentioned before. Now, when I am reading about them, I see they have been into the market since long. I will certainly read about them more. Maybe I never encountered them because my implementation isn’t that large at scale and hence we are implementing it using MQTT, AMQP, MongoDB etc.

    Also, I agree about AWS, it has the most number of services in cloud.

    Anyway, Thanks for answering my spectrum of questions from IoT message persistence to IIoT. It has been a great discussion!

    Best of luck !


  4. Hello, I’m having a problem when I connect to the Rabbitmq mqtt network, Rabbit creates a non-mqtt Stomp connection,
    when localhost gives yes mqtt,
    can you help me


    1. Hi Jean Carlos,
      Would you have anymore details? If local MQTT works, have you enabled remote connections? What are you using for your remote MQTT connections? Arduino C++ library, Python etc. Are you trying to run the STOMP plugin along with MQTT?

      If your goal is to use MQTT you might want to run a native MQTT broker like Mosquitto instead of RabbitMQ.



  5. Pete thanks for the return.
    I use Stomp client together with MQTT client, I have Stomp clients localhost
    that consume the queues, and I have MQTT arduino clients that send messages via mqtt to the Rabbit’s queues, I didn’t activate the remote connections because I couldn’t,
    tested localhost client in python and it works
    I wanted to use Rabbit because it has lines that I can go on processing ..
    sorry for any mistake in the text i’m brazilian and i’m using a translator.


    1. Hi Jean Carlos,
      One thing to check is your user configuration/rights. Did you use rabbitmqctl to define an MQTT user rights and are you using that using in the Arduino connection.

      When an MQTT client provides no login credentials, the plugin uses the guest account by default which will not allow non-localhost connections.



    1. Hi Jean Carlos,
      My RabbitMQ server is in Linux, but it shouldn’t matter too much. See: https://www.rabbitmq.com/mqtt.html#config for info on how to configure MQTT and users.

      For reference below is the json file for my test server. You can use the RabbitMQ web management server (http://your_server:15672) to do imports / exports. Go to the bottom of the overview page. I wouldn’t recommend loading my file directly but you could export your file and check for what is different.




  6. Hi Pete, I still couldn’t do it, I did a test with the program you put here and it’s giving this error, Attempting MQTT connection … failed, rc = 5


    1. Hi Jean Carlos,
      I’m really sorry to hear that you’re still having problem. Unfortunately my being remote makes it tough to help you out.

      An MQTT connection error =5 is a user/password authorization problem. Are you able to make a superuser. Something like:

      sudo rabbitmqctl add_user admin1 admin1
      sudo rabbitmqctl set_permissions -p / admin1 “.*” “.*” “.*”
      sudo rabbitmqctl set_user_tags admin1 management administrator

      It’s also important to note that if you’re MQTT testing is on MS-Windows machines, Windows may be blocking your connections. If you’re on Windows ensure that your firewall is turned off. However this might not be enough if you’re in a corporate environment your IT dept might have put policies in place to block “non-standard” ports. I was once hit by this problem and I needed to get an independent 3rd party PC in to proven things out.

      Good luck with things


  7. Hi Pete, First I want to thank you, for stopping by to help me.
    I did what you told me, I disabled the Firewall, antivirus and created that user it worked, thanks to you


  8. Hi Pete, I’d like to create a similar project for a fish tank in order to check different parameters: O, CO2, temperature and ph of the water. So, Where can I start to to do this? Thanks


    1. Hi,
      I like RabbitMQ especially for projects where I need custom queues, routing and mixed protocols.

      However for small IoT projects I prefer MQTT wth an MQTT broker (like Mosquitto) it’s simple, light and it’s supported on low end devices like Arduno, NodeMCU etc.

      The nice thing about starting with MQTT is you can always migrate it from using an MQTT broker to RabbitMQ if your project requirements change.

      To start your project I’d look at how to get your I/O in, you’ll need some waterproof sensors. An example link: https://create.arduino.cc/projecthub/atlasscientific/arduino-ph-sensor-calibration-ea1b65?ref=tag&ref_id=aquarium&offset=0

      Good luck. It sounds like a fun project.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s