What is the MQTT Protocol: A gentle introduction
Written by: Nyior Clement
In today’s interconnected world, data flows between systems incessantly. Sometimes these systems communicate using various messaging protocols, one of which is the MQ Telemetry Transport (MQTT).
Picture this: you’re watering your garden from miles away. With a quick tap on your smartphone, the sprinklers turn on, ensuring your plants get just the right amount of water. Moments later, a notification pops up confirming the task is done. Behind the scenes, this seamless interaction is powered by the MQTT protocol.
What is MQTT?
In 1999, IBM engineers Andy Stanford-Clark and Arlen Nipper created MQTT. The protocol was specifically designed to perform well in unreliable networks, such as the satellite links often used in the oil and gas industry at that time. Traditional messaging protocols were too heavy for the limited bandwidth and power of these systems.
At its core, MQTT is a lightweight messaging protocol that helps devices communicate by sending messages to a central broker, which then distributes them to other devices that need the information. MQTT was built with simplicity and efficiency in mind, making it perfect for IoT devices like sensors and actuators. These devices have limited processing power, memory, energy, and are often used in challenging conditions, so they need a protocol that minimizes resource usage while maintaining reliable communication. MQTT excels in this role because it was designed with specific features that are tailored to the challenges at hand. Features like:
- Being very light weight
- Varying Quality of Service (QoS) levels
- Last Will and Testament
- Retained Messages etc.
We will eventually look at these features, one at a time, but first, let’s look at the key components of MQTT.
How does MQTT work?
To truly understand how MQTT works, it helps to start with its two main components: clients and brokers. These are the building blocks of communication in MQTT.
MQTT Clients and Brokers
An MQTT client is any device or application that uses an MQTT client library to send or receive messages. This could be a temperature sensor sending data, or a smartphone app displaying it. On the other hand, an MQTT broker acts like a central hub. It receives messages from clients and decides who needs to get them, making sure everything reaches the right destination. Without the broker, clients wouldn’t know how to find each other or share information.
Essentially, messages flow from clients to the broker and vice-versa, but how do these different components actually exchange information in this setup? That’s where MQTT’s publish-subscribe model comes into play.
The Publish-Subscribe Model
At the heart of MQTT is its publish-subscribe messaging model, which works differently from the more common request-response model. Here’s how it goes:
- A client, called the publisher sends a message to the broker. This message is labeled with a topic. A topic is like an address, specifying where the message should land in the broker. For example, a sensor might publish temperature data to a topic like
home/livingroom/temperature
. - Other clients, called subscribers register with topics that interest them. For example, when a client subscribes to
home/livingroom/temperature
, the broker will forward any messages from that topic to the client. - The broker acts as the middleman, ensuring messages are delivered only to subscribed clients.
This model makes MQTT flexible and scalable, allowing many devices to communicate without being directly connected to one another. As we’ve seen, central to the publish-subscribe model is the concept of topics. A topic is the backbone of MQTT’s message organization— let’s take a closer look at how it works.
Topics in MQTT
Topics are a key part of MQTT’s design. Think of an MQTT topic as a queue system arranged in a hierarchy similar to file paths in a storage system. Topics have names that can be separated into subtopics using the forward slash as a delimiter. Consequently, you can have topics that are broad categories or very specific ones. For instance:
home
could represent your entire house.home/livingroom
narrows it down to a specific room.home/livingroom/temperature
gets even more specific, focusing on just the temperature data.
This structure allows for both flexibility and precision. A client interested in all living room data might subscribe to home/livingroom/#
, where #
is a wildcard to match anything under that topic.
Both publishers and subscribers can create MQTT topics. You should know that MQTT topics are case-sensitive. For example, home/livingroom
and Home/LivingRoom
are two different topics.
With clients, brokers, and the publish-subscribe model working together, MQTT creates a system that’s both simple and powerful. In the next section, we’ll take a closer look at the features that make MQTT stand out as the protocol of choice for IoT.
Key MQTT features
As mentioned earlier, from the get-go, the MQTT protocol was designed for resource-constrained devices and low-bandwidth, high-latency, or unreliable networks. So the protocol had features tailored for these conditions.
Lightweight Protocol
MQTT was designed to be minimalistic, with concise message headers and a compact payload, reducing the amount of data that needed to be sent across the network. MQTT also focuses on just one messaging pattern — publish/subscribe.
Quality of Service (QoS) Levels
MQTT introduced different levels of message delivery guarantees, allowing for trade-offs between guaranteed message delivery and bandwidth usage. You can optionally specify one of three QoS levels when publishing a message: 0, 1, 2
client.publish("some/topic", "Hello World", { qos: 1 }, function (err) {
if (!err) {
console.log("Message sent!");
}
});
QoS 0 has the lowest bandwidth usage, but also the lowest delivery guarantee. QoS 2 has the highest bandwidth usage and the highest delivery guarantee as well.
Last Will and Testament
Given the unreliable nature of the networks MQTT was designed to be used in, devices could set a “last will” message that the broker sends if they unexpectedly disconnect. This information allows subscribers to respond according to their requirements. The last will is usually specified by a client at connection time:
const options = {
will: {
topic: "some/topic",
payload: "Client has unexpectedly disconnected",
qos: 1,
retain: true,
},
};
const client = mqtt.connect("mqtt://broker-url", options);
Retained Messages
MQTT brokers could be configured to retain the most recent message on a topic, ensuring that devices coming online after downtime receive the latest message immediately without waiting for updates.
client.publish("some/topic", "Hello World", { retain: true }, function (err) {
if (!err) {
console.log("Message sent and retained!");
}
});
All these features and many others combine to make MQTT successful in these challenging scenarios. Its success showcase its potential for other use cases as well. With the rise of the Internet of Things (IoT), where many devices face similar constraints of limited power, bandwidth, and unreliable connections, MQTT became an ideal choice. Its simplicity, lightweight nature, and features tailored for constrained environments made it a leading protocol for IoT deployments.
MQTT and LavinMQ
LavinMQ, the message broker we built from the ground up, has traditionally only supported the AMQP 0-9-1 protocol. However, with the upcoming release of LavinMQ 2.1, we’re adding support for the MQTT 3.1 protocol.
Check out our using LavinMQ with MQTT documentation for more information on this.