MQTT QoS (Quality of Service) is a key feature, which provides different levels of assurance that a message will be delivered to the intended recipient. In this blog post, we will go deeper into the concept of QoS in MQTT and explore the different levels of QoS available in the protocol.
What is QoS?
Quality of Service (QoS) in MQTT is a feature that provides different levels of assurance that a message will be delivered to the intended recipient. The QoS levels in MQTT range from 0 to 2, with each level providing a different level of assurance that a message will be delivered.
QoS 0: At this level, the message is sent only once and is not guaranteed to be delivered. This level should be used for messages that are sent over reliable communication links or that can be missed without a problem.
QoS 1: At this level, the message is sent only once and is guaranteed to be delivered at least once. The sender receives a PUBACK response to indicate successful delivery.
QoS 2: At this level, the message is sent only once and is guaranteed to be delivered exactly once. The sender receives a PUBREC, PUBREL, and PUBCOMP response to indicate successful delivery.
Why MQTT QoS is important?
QoS is a key feature of the MQTT protocol. MQTT QoS gives the client the power to choose a level of service that matches its network reliability and application logic. Because MQTT manages the re-transmission of messages and guarantees delivery (even when the underlying transport is not reliable), QoS makes communication in unreliable networks a lot easier.
When should we use MQTT QoS?
|At most once delivery
|This level should be used for messages that are sent over reliable communication links or that can be missed without a problem.
|At least once delivery
|The message is not considered complete until the sender receives a PUBACK response to indicate successful delivery.
|Exactly once delivery
|This level should be used where the highest level of message delivery reliability is required, and where it is critical that a message is delivered exactly once and not lost or duplicated.
QoS 0: This level is best suited for situations where the message being sent is not critical and can be missed without causing any harm. For example, sending a message to update the temperature reading of a room in a building can be sent with MQTT QoS 0, as missing the message will not cause any harm.
QoS 1: This level is best suited for situations where the message being sent is critical and should be delivered at least once. For example, sending a command to turn off a machine in a factory should be sent with QoS 1, as missing the message could cause harm or lead to production downtime.
QoS 2: This level is best suited for situations where the message being sent is extremely critical and should be delivered exactly once. For example, sending a command to stop an emergency shutdown procedure in a nuclear power plant should be sent with QoS 2, as missing the message could cause severe harm.
There is very good use case of MQTT QoS in persistent session. In relation with persistent session, QoS 1 and QoS 2 are used when a device reconnects after a disconnection with a persistent session. The broker will attempt to redeliver any messages that were pending when the client disconnected, up to the QoS level that the device was subscribed with. This way persistent sessions, combined with QoS 1 and QoS 2, help to ensure that messages are not lost and that the device picks up where it left off, even in case of disconnections.
If interested, please read MQTT persistent session in detail on this page.
How QoS Works in MQTT
The QoS levels in MQTT work by using a combination of acknowledgement messages and flow control mechanisms. When a client publishes a message to a topic, the broker sends an acknowledgement message to the client to confirm that the message has been received. The type of acknowledgement message sent depends on the QoS level of the message.
It is also known as “fire and forget,” is the minimal service level in MQTT. This level guarantees a best-effort delivery but does not provide any guarantee of delivery. The recipient does not send an acknowledgement message, and the message is not stored or retransmitted by the sender. It is important to note that while MQTT QoS 0 provides a basic level of service, it should only be used for messages that can be missed without any negative consequences.
In MQTT QoS level 1, a message is guaranteed to be delivered at least once to the receiver. The sender holds onto the message until it receives a PUBACK packet from the receiver, confirming receipt. It’s possible for the message to be sent multiple times. The sender uses a packet identifier to match the PUBLISH packet with the corresponding PUBACK packet.
If no PUBACK is received in a timely manner, the PUBLISH packet is resent. When a receiver receives a message with MQTT QoS 1, it can process it immediately. For example, a broker would send the message to all subscribing clients and then send a PUBACK packet. If the publishing client resends the message, a DUP flag is set. However, in MQTT QoS 1, this flag is only used internally and is not processed by the broker or client. The receiver will still send a PUBACK regardless of the DUP flag.
In MQTT QoS level 2, a message is guaranteed to be delivered exactly once to the receiver. The sender sends the message with a unique packet identifier, and the receiver sends back a PUBREC packet to confirm receipt. The sender then sends a PUBREL packet with the same packet identifier, and the receiver sends back a PUBCOMP packet to confirm final delivery.
This two-step process ensures that the message is delivered only once and that both the sender and receiver are aware of successful delivery. If any of the packets are not received in a timely manner, they will be resent. When a receiver receives a message with MQTT QoS 2, it can process it immediately, and the broker or client will handle the two-step confirmation process for successful delivery.
Additionally, MQTT uses a flow control mechanism called a window size to limit the number of unacknowledged messages that a client can send at a time. This helps to prevent the client from overwhelming the broker with too many messages at once. The window size is determined by the QoS level of the messages being sent.
Best practices of using MQTT QoS
- Use the appropriate MQTT QoS level: Choose the appropriate QoS level based on the importance of the message and the potential consequences of missing the message. e.g. in case of MQTT persistent session use QoS1 or QoS2
- Monitor network conditions: Monitor the network conditions to ensure that the communication link is reliable. If the network conditions are poor, consider using a lower QoS level to prevent messages from being lost.
- Use unique client ids: Use unique client ids for each client to ensure that messages are delivered to the correct recipient.
- Monitor broker resources: Monitor the resources of the broker to ensure that it has enough resources to handle the messages being sent with the chosen MQTT QoS level.
- Use of Retain Flag: If the retain flag is set to 1, the broker will store the last message sent to a topic with QoS > 0 and send it to new subscribers. This can be useful for sharing the current state of a device for example.
In this blog post, we have explored the concept of Quality of Service (QoS) in MQTT and the different levels of MQTT QoS available in the protocol. We have also discussed when to use different levels of MQTT QoS and how QoS works in MQTT. Additionally, we have provided some best practices for using QoS in MQTT to ensure reliable and efficient communication. With the appropriate use of MQTT QoS, we can provide the necessary guarantees for message delivery and help to ensure the integrity and reliability of data in IoT and other real-time communication systems.