What is MQTT Quality of Service (QoS) 0,1, & 2? – MQTT Essentials: Part 6
MQTT Quality of Service (QoS) is an agreement between the message sender and receiver that defines the level of delivery guarantee for a specific message. Here’s Part 6 of MQTT Essentials, where we will look deeper at the different Quality of Service (QoS) levels in MQTT. If you are looking to understand MQTT Topics, Wildcards, & Best Practices, check out Part 5 of the series. Else, let’s dive in.
Table of Contents
- What is Quality of Service (QoS) in MQTT?
- How to Examine Message Delivery in MQTT?
- Why is Quality of Service (QoS) Important?
- What are the Key Considerations for QoS in MQTT?
- What are the Best Practices While Using MQTT Quality of Service (QoS) 0,1, & 2?
- Queuing of QoS 1 and 2 messages
What is Quality of Service (QoS) in MQTT?
MQTT provides three levels of QoS:
- At most once (QoS 0)
- At least once (QoS 1)
- Exactly once (QoS 2)
How to Examine Message Delivery in MQTT?
When discussing QoS in MQTT, it’s important to consider message delivery from the publishing client to the broker and from the broker to the subscribing client. These two aspects of message delivery have subtle differences.
The client that publishes a message to the broker defines the QoS level for the message during transmission. The broker then transmits the message to subscribing clients using the QoS level defined by each subscribing client during the subscription process. If the subscribing client defines a lower QoS level than the publishing client, the broker will transmit the message with the lower QoS level.
Understanding how message delivery works in MQTT sets the foundation for appreciating the significance of Quality of Service (QoS) levels in ensuring reliable communication between the publishing client, broker, and subscribing client.
Why is Quality of Service (QoS) Important?
Quality of Service (QoS) is crucial in MQTT due to its role in providing the client with the ability to select a service level that aligns with both the network reliability and the application’s requirements. MQTT’s inherent capability to handle message re-transmission and ensure delivery, even in unreliable network conditions, makes QoS essential for facilitating seamless communication in such challenging environments. By offering different QoS levels, MQTT empowers clients to optimize their network usage and achieve the desired balance between reliability and efficiency.
Now that we understand the significance of Quality of Service (QoS) in MQTT, let’s delve into the inner workings of QoS and explore how it operates to ensure reliable message delivery in varying network conditions.
How does QoS 0 work in MQTT?
At the lowest level, QoS 0 in MQTT offers a best-effort delivery mechanism where the sender does not expect an acknowledgment or guarantee of message delivery. This means that the recipient does not acknowledge receiving the message, and the sender does not store or re-transmit it. QoS 0, commonly called “fire and forget,” functions akin to the underlying TCP protocol, where the message is sent without further follow-up or confirmation.
How does QoS 1 work in MQTT?
In QoS 1 of MQTT, the focus is on ensuring message delivery at least once to the receiver. When a message is published with QoS 1, the sender keeps a copy of the message until it receives a PUBACK packet from the receiver, confirming the successful receipt. If the sender doesn’t receive the PUBACK packet within a reasonable time frame, it re-transmits the message to ensure its delivery.
Upon receiving the message, the receiver can process it immediately. For example, if the receiver is an MQTT broker, it distributes the message to all subscribing clients and responds with a PUBACK packet to acknowledge the receipt of the message.
It’s important to note that in QoS 1, if the publishing client sends the same message again, it sets a duplicate (DUP) flag. However, this flag is used for internal purposes and is not processed by the broker or client. Regardless of the DUP flag, the receiver still sends a PUBACK packet to acknowledge the receipt of the message, ensuring the sender is aware of the successful delivery.
This approach of QoS 1 strikes a balance between reliability and efficiency, guaranteeing that the message reaches the receiver at least once while allowing for potential duplicates to be handled appropriately.
How does QoS 2 work in MQTT?
QoS 2 offers the highest level of service in MQTT, ensuring that each message is delivered exactly once to the intended recipients. To achieve this, QoS 2 involves a four-part handshake between the sender and receiver.
When a receiver gets a QoS 2 PUBLISH packet from a sender, it processes the publish message accordingly and replies to the sender with a PUBREC packet that acknowledges the PUBLISH packet. If the sender does not get a PUBREC packet from the receiver, it sends the PUBLISH packet again with a duplicate (DUP) flag until it receives an acknowledgement.
Once the sender receives a PUBREC packet from the receiver, the sender can safely discard the initial PUBLISH packet. The sender stores the PUBREC packet from the receiver and responds with a PUBREL packet, the receiver discards all stored states and replies with a PUBCOMP packet.
After the receiver gets the PUBREL packet, it can discard all stored states and answer with a PUBCOMP packet (the same is true when the sender receives the PUBCOMP). Until the receiver completes processing and sends the PUBCOMP packet back to the sender, the receiver stores a reference to the packet identifier of the original PUBLISH packet. This step is important to avoid processing the message a second time.
After the sender receives the PUBCOMP packet, the packet identifier of the published message becomes available for reuse.
When the QoS 2 flow is complete, both parties are sure that the message is delivered and the sender has confirmation of the delivery.
If a packet gets lost along the way, the sender is responsible to retransmit the message within a reasonable amount of time. This is equally true if the sender is an MQTT client or an MQTT broker. The recipient has the responsibility to respond to each command message accordingly.
What are the Key Considerations for QoS in MQTT?
While understanding QoS in MQTT, there are several important aspects to keep in mind:
Downgrade of QoS
The QoS levels defined by the sender and receiver can differ. The client sending the message to the broker defines the QoS level, while the broker uses the QoS defined by the receiver during subscription. For example, if the sender uses QoS 2 and the receiver subscribes with QoS 1, the broker delivers the message to the receiver with QoS 1. This can result in multiple deliveries of the same message to the receiver.
Packet identifiers are unique per client
Packet identifiers used for QoS 1 and 2 are unique between a specific client and a broker within an interaction. However, they are not unique across all clients. Once a flow is complete, the packet identifier becomes available for reuse. This is why the packet identifier does not need to exceed 65535 , as it is unrealistic for a client to send more messages than that without completing an interaction
What are the Best Practices While Using MQTT Quality of Service (QoS) 0,1, & 2?
We are often asked for advice about how to choose the correct QoS level. Selecting the appropriate QoS level depends on your specific use case. Here are some guidelines to help you make an informed decision:
Use QoS 0 when:
- You have a completely or mostly stable connection between sender and receiver. A classic use case for QoS 0 is connecting a test client or a front end application to an MQTT broker over a wired connection.
- You don’t mind if a few messages are lost occasionally. The loss of some messages can be acceptable if the data is not that important or when data is sent at short intervals
- You don’t need message queuing. Messages are only queued for disconnected clients if they have QoS 1 or 2 and a persistent session.
Use QoS 1 when:
- You need to get every message and your use case can handle duplicates. QoS level 1 is the most frequently used service level because it guarantees the message arrives at least once but allows for multiple deliveries. Of course, your application must tolerate duplicates and be able to process them accordingly.
- You can’t bear the overhead of QoS 2. QoS 1 delivers messages much faster than QoS 2.
Use QoS 2 when:
- It is critical to your application to receive all messages exactly once. This is often the case if a duplicate delivery can harm application users or subscribing clients. Be aware of the overhead and that the QoS 2 interaction takes more time to complete.
Queuing of QoS 1 and 2 messages
All messages sent with QoS 1 and 2 are queued for offline clients until the client is available again. However, this queuing is only possible if the client has a persistent session.
That’s the end of Part 6 of our MQTT Essentials series. We hope that you find this information useful. In the next article, we cover a subject that is closely associated with Quality of Service levels: persistent sessions in MQTT.
Are you enjoying our content? Then sign up for our newsletter below. If you prefer RSS, you can subscribe to our RSS feed here. Do check out MQTT Glossary to know all the key MQTT terminologies. Watch the video below that complements the concepts discussed in this article.
FAQs on QoS in MQTT
You can assign the QoS level of a message in the PUBLISH packet.
QoS messages are lost since there is no acknowledgement mechanism at this level. If a message is lost in transit due to network issues, or if the subscriber is offline at the moment the message is sent, the message will be lost. The publisher has no way of knowing if the message was successfully received and will not attempt to resend it.
If multiple clients are subscribed to the same topic but with different Quality of Service (QoS) levels, the broker delivers the message to each client according to the QoS level at which that client is subscribed, rather than the QoS level at which the message was published.
The broker will deliver the retained message at the QoS level that was set when the message was published or the QoS level of the subscription, whichever is lower.
If a message sent with Quality of Service (QoS) level 0 is not received by the subscriber, the message is lost.
To provide this guarantee, QoS 2 introduces a four-step handshake between the publisher and the recipient (which could be a broker or a client, depending on the direction of the message). This process involves the usage of PUBLISH, PUBREC, PUBREL, and PUBCOMP messages.
If the broker received the original message and sent a PUBACK, but the PUBACK didn't reach the publisher (again, maybe due to a network issue), then the broker will receive the duplicate message.When publishing a message, include a unique identifier or a sequence number in the payload.
Message Overhead - Thd additional communication results in more network traffic and uses more bandwidth compared to QoS 0 or 1. Delivery Latency - The additional round trips required for the four-step handshake mean that the end-to-end latency for delivering a message is higher in QoS 2 compared to QoS 0 or 1.
Yes, using higher Quality of Service (QoS) levels in MQTT does impact bandwidth and network utilization.
When a publisher sends a message to a broker, it specifies a QoS level for the message. The broker will acknowledge and handle the message according to the QoS level specified by the publisher.When a broker sends a message to a subscriber, the QoS of the message delivery is the lower of the QoS level at which the message was published and the QoS level at which the subscriber has subscribed to the topic.
In MQTT, when the network connection is lost, the treatment of QoS 1 and QoS 2 messages depends on the stage of the message delivery process at which the connection was lost, and whether or not persistent sessions (also known as clean sessions) are being used.
MQTT doesn't have explicit mechanisms for handling backpressure built into the protocol itself, but there are ways that the concept is relevant and can be managed, especially in relation to the Quality of Service (QoS) levels.
Although the MQTT protocol does not explicitly define a limit on retransmissions, the client library or broker you're using might allow you to configure this. The specifics would depend on the particular implementation you're using.