When the term ‘quality of service’ comes to mind, you’re probably thinking about the standards at which someone provides a service – and you’d be right. For an MQTT message to reach its destination, it has to overcome a path from a publisher to a broker, and then from the broker to a subscriber. In other words, there are at least two stages of delivery where a message could get lost in the transmission process. That is why MQTT QoS is necessary, as message loss directly impacts the reliability of our IoT projects.
With MQTT QoS explained, you can differentiate between QoS levels and select the right one.
Before we dive deeper into the MQTT QoS topic, you should understand the basics of MQTT. This article on our blog brilliantly captures everything you need – check it out here.
What is MQTT Quality of Service (QoS)?
MQTT QoS is a level of service that serves as a consensus between a publisher and a broker on one hand, and the broker and a subscriber – on the other regarding a guarantee to successfully dispatch an MQTT message. Therefore, when we look at MQTT messaging process in general, we can see precisely two publishing stages that we need to consider during an MQTT message transmission:
- From a publisher (data sender) to a broker (data receiver), and
- From the broker (data sender) to a subscriber (data receiver).
In every message transmission, the broker acts as a middleman between the publisher and subscriber, performing a role of both a receiver and sender of data. To enable messaging, the MQTT broker completes a number of steps.
When an MQTT client is trying to subscribe to a topic, it sends a SUBSCRIBE packet that, among other information, also includes a wanted QoS level. Read our ultimate guide to learn what MQTT packet is. The broker, in turn, answers this request with a SUBACK packet and specifies a corresponding return code to confirm the subscription (including the QoS level).
When an MQTT client wants to publish a message to a topic, it sends a PUBLISH packet specifying the desired QoS level.
Now that we better understand MQTT QoS, let’s learn more about the different QoS levels and what they mean.
What are the MQTT QoS levels?
There are three levels to note in MQTT QoS: 0, 1, 2. We’ve summarized what each level means below:
- QoS 0: at most once
- QoS 1: at least once
- QoS 2: exactly once
We will talk about what QoS 0, 1, 2 in MQTT means in the next few sections, but let’s summarise what this means from a publisher’s or subscriber’s point of view.
|0: at most once
|Will send a message only once.
|Might receive or might not receive the message.
|1: at least once
|Will send a message at least once as long as an acknowledgement is received or the command to end the transmission is received.
|It is likely to receive the message at least once (it is possible that the message can be received more than once).
|2: exactly once
|Will only send a message once.
|Will only receive the message once.
With the information in this table, you should better understand each QoS level for a publisher or subscriber. Let’s explore each QoS level and how they work in real-life situations.
MQTT QoS 0
MQTT QoS 0 is one of the quality service levels in MQTT; it ensures that a message is sent only once but doesn’t guarantee delivery.
How MQTT QoS 0 works
Commonly known as the ‘fire and forget’ method, QoS 0 only guarantees that a message is sent but does not guarantee that it is received. This is because the broker does not wait for an acknowledgement from the receiver. So what happens is the following: an MQTT publisher sends a PUBLISH packet and specifies the QoS level in it, then the broker forwards it to the subscriber. This is it.
Since the broker does not need any acknowledgement, the publisher discards the message once it is sent. Simply put, the goal for MQTT QoS 0 is to blast its message out at most once.
MQTT QoS 0 example
An example of MQTT QoS 0 is the sensor at the entrance of a grocery store that counts the number of customers entering and exiting the store. In this scenario, the publisher sends the current count and does not need any acknowledgement; that is why it uses QoS 0.
MQTT QoS 1
Now, with MQTT QoS 1, things get a little more complex. The publisher will send a message at least once and will continue sending it until the broker receives an acknowledgement.
How MQTT QoS 1 works
QoS 1 ensures that a message will be delivered and received at least once. After the publisher (data sender) sends the message as part of the PUBLISH packet to the MQTT broker (data receiver), the broker (data receiver) responds to the publisher (data sender) with the acknowledgement PUBACK packet, and the sending process stops.
The publisher will continue sending this message if it does not receive a PUBACK packet.
For instance, a connection drops during message sending. In this case, once it is restored, the publisher will send the PUBLISH packet again.
We consider MQTT QoS 1 a pesky alarm clock that will not stop! At least it gets you up for work.
MQTT QoS 1 example
One scenario where MQTT QoS 1 is frequently used is in cars. If the driver’s seat belt is not fastened, the car sends an alert repeatedly till the driver fastens his seat belt. In this case, the publisher needs a response from the subscriber before the transmission is considered complete.
MQTT QoS 2
Okay, we saved the best for last. If QoS 0 was the lowest level of service, QoS 2 must be the highest one, right? Yes, QoS 2 is the highest level of service and is considered the most reliable but also the slowest MQTT quality of service.
You may wonder why QoS 2 is the slowest. Every message delivery requires a four-part verification between both tandems: a publisher and a broker, and the broker and a subscriber. This might seem tedious, but this process ensures that subscribers receive a message exactly once.
How MQTT QoS 2 works
As mentioned, every message delivered with MQTT QoS 2 has a four-part verification. The four packets that take part in the communication are:
- Publish received (PUBREC)
- Publish released (PUBREL)
- Publish complete (PUBCOMP)
After the data sender (a publisher or an MQTT Broker) sends a PUBLISH packet (including a unique PacketID value and the QoS set to 2) to the data receiver (an MQTT broker or a subscriber), the receiver answers with a PUBREC command (using the same PacketID) to confirm the receipt of the PUBLISH packet. Once the data sender gets the PUBREC packet, it deletes the initial PUBLISH packet while keeping the PacketID and the PUBREC packet.
The data sender then sends a PUBREL packet to the data receiver to confirm the receipt of the PUBREC packet that was formerly received. In the end, the data receiver sends a PUBCOMP packet with the PacketID of the initial PUBLISH packet to the data sender, indicating that the message delivery has been successful.
The broker processes packets cyclically, forwarding the PUBLISH packet for each message and then waiting for the PUBREC response to arrive from all subscribers. Once all subscribers have replied with a PUBREC, the broker removes the message stored in the inflight message queue. After that, it informs the subscribers of this with a PUBREL packet.
Moreover, all subscribers also maintain their inflight message queue, which allows them to compare incoming messages with those already received. This action ensures that a subscriber forwards the message to the coupled mechanisms once only. If the subscriber receives the PUBREL packet, it will delete the message from its inflight message queue and inform the broker about it by sending a PUBCOMP command.
If neither the broker nor the subscriber receives one of these packets, the message exchange for this particular topic will interrupt. All new messages a publisher sends will be queuing in the inflight queue while the broker will continue sending a PUBLISH or PUBREL command with a dup flag. However, at the same time, the broker will continue receiving and forwarding messages for all other topics.
MQTT QoS 2 example
One can use this QoS level in an automated factory production line, where robotics are used in each assembly station. However, the process cannot continue to the next station until the previous station is completed, which is why MQTT QoS 2 is most suitable.
The difference in MQTT QoS levels for publishing and subscribing
Understanding that a publisher and a subscriber can submit completely different values of desired QoS levels is essential. When it happens, it is crucial to know how the broker will act to understand which QoS to use to deliver the MQTT message. So the question is – if this happens, which level should or will MQTT use?
In earlier sections of this article, we covered the basics of each QoS level. In any case, we know there was a lot to digest, so we’ve also included a quick recap of each level below:
- 0: at most once
- 1: at least once
- 2: exactly once
The rule of thumb is to follow the lowest QoS level when there are different QoS levels. A broker will use the subscriber’s QoS level if the publisher specifies a higher QoS level than a subscriber. The data transfer from the publisher to the broker will still be the QoS level the publisher has set. On the other hand, if a publisher specifies a lower QoS than a subscriber, the MQTT broker uses the publisher’s QoS level instead.
It is because a publisher or subscriber can attain a lower QoS than defined, but they will not be able to achieve a higher QoS. Therefore, if a publisher uses QoS 1 and a subscriber uses QoS 0, the subscriber cannot deliver a higher MQTT QoS, meaning that the overall QoS should be 0.
Let’s look at other scenarios where publishers and subscribers have different QoS and the overall QoS in each scenario.
|QoS Publisher >> Broker
|QoS Broker >> Subscriber
|1 or 2
|1 or 2
|1 or 2
How to choose the right QoS level for your project
You have learned a lot about MQTT QoS and how each level works. This section will share more about the scenarios and conditions where each QoS level is most suited. With this information, you can make an informed decision when picking the right QoS level for your project.
By now, you know that each QoS level has different behaviors. QoS 0 means the message is sent at most once with no acknowledgement. With QoS 1, the message is sent at least once with one acknowledgement. Lastly, for QoS 2, the message is sent exactly once with a four-step verification process.
When should you use MQTT QoS 0?
With MQTT QoS 0, you should use this if:
- Your publishers and subscribers have a stable connection.
- You are okay with the possibility of some dropped or lost messages.
- Message queuing is not that important for your project.
- Data transmission will use the least bandwidth.
A typical scenario for MQTT QoS 0 would be periodic updates or announcements that are not time-sensitive. For instance, the fuel level sensor in a piece of machinery, where you can afford to miss some updates.
When should you use MQTT QoS 1?
For MQTT QoS 1, you should use this if:
- Every message must be received.
- You can deal with receiving duplicate messages.
A possible situation where you would require MQTT QoS 1 will be if public transport breaks down. In this case, you need to send updates about when the service can resume. In this case, duplicates can be ignored as users need to receive every message.
When should you use MQTT QoS 2?
Although MQTT QoS 2 is the highest level of service, it is worth noting that there is significant overhead involved when using this level. However, there are certain cases where QoS 2 is necessary.
You should use QoS 2 if:
- Every message must be received only once.
- Your system cannot accept duplicates.
- You can handle a slower message delivery.
- Data transmission will use the highest volume of bandwidth.
- A lost message could result in loss of life or cause significant harm to end users.
Some situations where one can use MQTT QoS 2 are in hospitals or stock exchanges since these applications do not allow duplicates. It is also important to note that many avoid using QoS 2 unless there are exceptional cases, as described above.
Now that you know more about MQTT QoS, you are ready to start using it in your projects. Besides picking the proper QoS, the MQTT broker also plays a significant role in MQTT message delivery. Therefore, it is also essential to choose the right MQTT broker. We recommend using the Pro Edition for Mosquitto, which provides HA and performance for cloud and on-premises MQTT deployments.
If you’re not sure about purchasing the pro version yet, there is a free 14-day trial. You can test basic MQTT broker scenarios using the trial, access existing REST APIs, and more! Sign up for it here.
About the author
Roger has a background in Electronic Engineering academic research focusing on the design of scientific optical imaging sensors, accompanying control and acquisition systems, and other embedded designs.
He has 6 years of Academic teaching responsibility, teaching semiconductor chip design, embedded design, and programming.
Roger started Mosquitto as a hobby project in 2009, which gained rapid popularity and contributed to the widespread adoption of MQTT as an IoT protocol. He also developed an MQTT client library in Python, and both projects became part of the Eclipse Foundation in 2014/15. In 2018, Roger joined Cedalo to develop Mosquitto further, starting with implementing MQTT v5.0 support.