MQTT Quality Of Service Indicates the Service Quality

What is quality of Service QoS?

QoS is a protocol defined at the sender and receiver of a message to ensure the delivery level of a particular message.

There are three QoS levels in MQTT:

  • At most once(0) at most once
  • At least once(1) At least once
  • Exactly once(2) exactly once

The cost of completing these three levels of message delivery is also different, and we need to consider the actual scenario in the selection process.

When talking about QoS in MQTT, the message flow needs to be considered in two directions:

  1. Message publishing client -> proxy server
  2. Proxy server -> Message subscription client

Why is that?

The client defines QoS levels for publishing messages to the broker Borker. The broker delivers the message to the subscribing client using the QoS defined by the subscribing client when subscribing to the topic. If the QoS of the subscribing client is smaller than that of the publishing client, the message is delivered at a lower QoS level.

Just to emphasize QoS

QoS is a key feature of MQTT protocol. QoS enables the server to select the service level matching its network service quality. MQTT guarantees reliable transmission and resend of messages (even if the underlying transport is unreliable), and QoS makes it easier to communicate over unreliable networks.

QoS 0 at most once

The lowest QoS level is 0, sometimes referred to as “send and forget”. Messages are not acknowledged by the receiver and are not stored or retransmitted by the sender. It provides the same guarantee as the underlying TCP protocol

QoS 1 at least once

The level of QoS 1 guarantees that the message will be delivered to the receiver at least once, and the sender stores the message until he receives the PUBACK (publish confirmation) packet sent by the receiver. The message may be delivered once or more.

The sender uses the packetId in each packet to match the corresponding PUBACK packet, and resends the packet if the sender does not receive the PUBACK packet within a reasonable period of time.

A receiver can process a message with a QoS of 1 as soon as it is received, such as an MQTT broker can process the message as soon as it is received, send the message to the subscriber, and then send a PUBACK packet for confirmation.

Resend If the sender resends, it sets the DUP flag to true. In QoS 1 the receiver of a message sends a PUBACK packet regardless of the DUP.

QoS 2 exactly once

QoS 2 is the highest level of MQTT, which ensures that the message is delivered only once. QoS 2 is implemented based on a four-part handshake between the receiving and sending parties, which means that this level is the most secure and least efficient.

The sender and receiver of the message use the packetId of the original PUBLSH package to coordinate the delivery of the message.

When the message receiver receives the PUBLSH QoS 2 packet from the message sender, it can process the PUBLSH message accordingly and send a PUBREC (PUBLSH received) packet in response to the message sender confirming that the PUBLSH packet has been received, If the sender does not receive the PUBREC package from the receiver, it resends the PUBLSH package with the DUP logo until it receives an acknowledgement.

When the sender receives the PUBREC response from the receiver, it can discard the original PUBLSH packet and respond with a PUBREL (publish-release) packet

After receiving the PUBREL packet, the receiver can discard all relevant storage states and send the PUBCOMP (publication completed) packet to the sender. The sender can discard all relevant storage states upon receiving the PUBCOMP packet.

The recipient needs to store a reference to the original PUBLSH packet identifier, known as packetId, before receiving PUBREL and returning to PUBCOMP to prevent the data from being processed again. The packetId can be reused by the sender after receiving PUBCOMP.

When QoS 2 traffic transmission is complete, both the sender and the receiver confirm that the message has been delivered correctly.

If a packet is lost during this process, it is the responsibility of the sender to retransmit it at the appropriate time. Again, both the sender and the receiver are responsible for responding to the received data, whether they are client or broker agents.

In contrast to QoS 1, QoS 2 records packetId for de-weight. At this time, relevant resources need to be released, so PUBREL and PUBCOMP are added to confirm receipt of the last two steps so as to release resources. Messages are de-weight at the protocol level. QoS 1 levels require message packets to be de-duplicated at the Broker or Server side

In general, QoS 2 implements message de-duplication at the protocol level and is more suitable for low-memory client physical devices. If we have enough memory then using QoS 1 logic at the application layer for de-weighting is definitely a better choice.

Something you have to know

Some parts of QoS are easy to overlook, but these points are crucial to keep in mind.

QoS degradation

As mentioned above, we need to consider two aspects when considering messaging:

Client publisher -> Server proxy

Server proxy -> Client subscriber

Here messages will be delivered with the lowest QoS.

This means that when you want to use advanced QoS, you need to make sure that the QoS of both publishing and subscribing is consistent, or that the logic is processed at the application layer

The packet identifier packetId for a single client is unique

At QoS 1 and QoS 2 levels each client’s packetId is unique when interacting with a specific agent, but not unique among all clients. Once the flow is complete, the packetId can be reused. This reuse mechanism is the reason why packetId does not need to exceed 65535, and it is not practical to send more messages than this number in order to complete the interaction.

Best practices

When to use QoS 0?

Your application establishes stable and persistent connections in most cases.

You can tolerate partial loss of messages.

You don’t need a message queue. Messages are queued only for QoS 1 and 2.

When to use QoS 1?

You need to make sure that each message and your service can handle duplicate data. QoS 1 is the most common level and guarantees data arrival, but this creates duplicates, so your project must tolerate duplicates or be able to handle them properly.

You can’t afford the overhead of QoS 2, QoS 1 delivers messages much faster than QoS 2.

When to use QoS 2?

It is critical for your project that the message be delivered only once, and that your project cannot properly handle repetition on its own.

Longer interactions with QoS 2 can be tolerated.

You can follow the public account of dying stranded and receive push. If you have any technical questions or questions, you can directly add my wechat account dyinggq and we can discuss together. Hope you found this article helpful.