Skip to content

MQTT 5 Subscription Options: A Quick Guide

by Jens Deters
22 min read

MQTT 5.0 introduced significant enhancements to the subscription process, allowing for more granular control over message delivery. By understanding and leveraging these subscription options, you can create more sophisticated and efficient MQTT-based systems, tailoring message delivery to your specific application requirements.

In this blog, we’ll explore the technical details of these subscription options and their implications for MQTT implementations. We will also demonstrate their usage using the HiveMQ Cloud MQTT broker and MQTT.fx client.

Understanding MQTT 5 Subscription Options

MQTT 5.0 offers four key subscription options:

  1. QoS (Quality of Service)

  2. No Local

  3. Retain As Published

  4. Retain Handling

MQTT 3.1.1 offers only the QoS subscription option, but in MQTT 5.0, the default behavior of these new subscription options remains aligned with MQTT 3.1.1. This consistency ensures a smooth transition for users upgrading from MQTT 3.1.1 to MQTT 5.0.

Now, let’s dive deeper! These subscription options are encoded in a single byte within the SUBSCRIBE packet. The bit layout is as follows:

MQTT 5 Subscription Options

Where:

  • Bits 7-6: Reserved for future use

  • Bits 5-4: Retain Handling

  • Bit 3: Retain As Published 

  • Bit 2: No Local (NL)

  • Bits 1-0: Maximum QoS

Let's dive into each option and see how they work in practice.

Quality of Service (QoS)

QoS determines the reliability of message delivery. In MQTT 5, the subscription QoS represents the maximum QoS level the server can use when forwarding messages to the subscriber. And QoS in MQTT 5 subscriptions works similarly to previous versions, but with added nuances. Here are the points that you need to make a note of when using this subscription option:

  • QoS is represented by the last two bits of the subscription options byte.

    • 00: QoS 0

    • 01: QoS 1

    • 10: QoS 2

    • 11: Reserved (must not be used)

  • The granted QoS in the SUBACK packet may be lower than the requested QoS.

  • Messages published with a higher QoS (e.g., 2) are downgraded to the lower QoS (e.g., 1) when delivered if the subscription option is lower.

  • MQTT clients must be prepared to handle messages at any QoS up to and including the requested and granted QoS.

  • Servers must not upgrade the QoS of messages to match the subscription QoS.

To learn more about QoS, read our blog What is MQTT Quality of Service (QoS) 0,1, & 2? If you are looking to master MQTT QoS, get your copy of Quality of Service in MQTT: The Ultimate Guide.

No Local Option

The No Local option, when enabled, prevents a client from receiving messages that it has published itself. This introduces a new concept in message routing within MQTT brokers. This feature is particularly useful in scenarios where you don't want to process your own messages, such as in MQTT bridging setups. 

Here are some points to note when using this subscription option:

  • It is represented by bit 2 of the subscription options byte.

  • When set to 1, the server must not forward messages published by the client back to the client itself. This is determined by the clientID of the client.

  • In clustered broker setups, this information must be shared across nodes.

Example Scenario:

  1. Client A subscribes to "livingroom/sensor1/temperature" with the "No Local" flag set to true.

  2. Client A publishes a message to this topic.

  3. Client A will not receive messages it just published because "No Local" is enabled.

  4. If Client B subscribes to the same topic and the "No Local" flag is not enabled for Client B, it will receive the messages published by Client A to this topic.

Important: The "No Local" flag does not affect how the broker stores or handles retained messages; it only impacts whether or not the client that publishes the message will receive it back based on its subscription.

Retain As Published

The Retain As Published subscription option in MQTT 5 allows subscribers to control how the RETAIN flag is handled for messages they receive. This option is primarily useful in bridging scenarios, where MQTT servers are connected to each other and forwarding messages between them or especially in complex network topologies involving multiple interconnected MQTT brokers. 

It has two possible values:

  • 0 (default): The RETAIN flag is cleared (set to 0) for all messages forwarded to the subscriber.

  • 1: The RETAIN flag is preserved as it was when the message was originally published.

To use this option, set bit 3 of the Subscription Options byte to 1 when subscribing to a topic. Most MQTT client libraries like the HiveMQ MQTT Client provide a way to set this option when creating a subscription. 

Note that when a subscriber sets 'Retain As Published' to 1:

  1. Messages forwarded to that subscriber keep their original RETAIN flag value.

  2. This allows the receiving MQTT broker to identify and store retained messages properly, even when received through an MQTT bridge.

Example Scenario:

“Retain As Published” = false
  1. Client A publishes a message to "livingroom/sensor1/temperature" with the retain flag set (retain = true).

  2. The broker stores the retained message and marks it as such.

  3. Client B subscribes to "livingroom/sensor1/temperature" without the "Retain As Published" flag. 

  4. The broker sends the retained message to Client B on subscription. To inform the recipient that this message is THE “retained” message, the retained flag is “true” in this case. 

  5. Client A publishes the next message to "livingroom/sensor1/temperature" with the retain flag set (retain = true).

  6. Client B receives this message, but this time the broker has removed the retain flag, as this is the "normal" message flow, since Client B is still subscribed to "livingroom/sensor1/temperature."

Example Scenario –“Retain As Published” = false

“Retain As Published” = true
  1. Client C subscribes to "livingroom/sensor1/temperature" with the "Retain As Published" flag set to true. 

  2. The broker sends the retained message to Client C on subscription with retained flag = true. Again to indicate the client this message is THE stored retained message.

  3. Client A publishes the next message to "livingroom/sensor1/temperature" with the retain flag set (retain = true).

  4. This time the broker sends this message to Client C, preserving the original retain flag state (retain = true). 

  5. Retain = true applies to all subsequent messages to this subscription of Client C.

Example Scenario –“Retain As Published” = trueFor more details on Retained Messages, read our blog, What are Retained Messages in MQTT? 

Retain Handling

The "Retain Handling" option in MQTT v5.0 provides more granular control over how retained messages are delivered to subscribers. This feature was introduced to give subscribers more flexibility when dealing with retained messages, especially in situations where they may or may not want to receive retained messages.

Represented by bits 5-4 of the subscription options byte, it has three modes:

  •  0: Send retained messages at subscription time

  •  1: Send retained messages at subscription time, but only for new subscriptions

  •  2: Do not send retained messages at subscription time

In layman's terms,

Value 0: “Send retained messages at subscription time”

This is the default behavior. The broker will send the retained message immediately when the client subscribes to a topic, regardless of whether the subscription already existed before. The client will receive the last retained message, ensuring that it gets the most up-to-date (retained) message on that topic.

Example: 

Client A subscribes tolivingroom/sensor1/status,” and if there's a stored retained message, it will receive it instantly, even if Client A already has an active subscription to that topic.

Value 1: “Send retained messages at subscription time, but only for new subscriptions”

The broker will send the retained message only if the subscription is new, meaning that if the client already had an active subscription to the topic, it will not receive the retained message again. 

Example: 

  1. Client A connects to a broker and is starting a new session

  2. Client A is programmed to subscribe to the topic livingroom/sensor1/status with the Retain Handling “Send retained messages at subscription time, but only for new subscriptions” on every connection. 

  3. Client A subscribes to this topic after connecting and receives a retained message of "online." 

  4. Client A disconnects from the broker and then reconnects, but this time without creating a new session. Thus Client A still has an active subscription to livingroom/sensor1/status,“ and the broker will not send a retained message. 

  5. Now, as programmed, Client A subscribes to livingroom/sensor1/statuswith the Retain Handling “Send retained messages at subscription time, but only for new subscriptions” option. 

  6. Technically this is a new subscription to the topic Client A is already subscribed to. 

  7. But the broker will not send a retained message on this subscription in this case.

Value 2: “Do not send retained messages at subscription time”

In this mode, the broker does not send any retained messages when a client subscribes to a topic, even if there is a retained message stored. This is useful in situations where it is required that a client only receives newly published messages and has no interest in receiving the previously retained messages from the topic.

Example: 

Client A subscribes to alerts/critical” but does not want to receive any previously retained alert messages. It will only receive new alerts that are published after the subscription.

Shared Subscription

While not strictly a subscription option, MQTT 5 introduced shared subscriptions as a core feature. Shared subscriptions allow multiple clients to share the message load for a single subscription. For more information, read our blog on MQTT Shared Subscriptions.

Technical Implications While Using MQTT 5 Subscription Options

Implementing these subscription options in an MQTT broker requires careful consideration:

  1. Performance Impact: Checking and applying these options for each message increases processing overhead.

  2. Memory Usage: Brokers need to store additional metadata for each subscription, potentially increasing memory consumption.

  3. Scalability: In large-scale deployments, the additional complexity of these options can impact performance, but efficient MQTT brokers handle this to maintain scalability.

  4. Interoperability: When bridging between MQTT 3 and MQTT 5 brokers, special handling is required to map these options correctly.

A Demo: Using HiveMQ Cloud and MQTT.fx

To demonstrate some of these concepts, we'll use the HiveMQ Cloud and MQTT.fx client, which supports MQTT 5 Subscription Option features.

Initial Setup: Connecting HiveMQ Cloud with MQTT.fx

1. Visit Get HiveMQ and log in to the HiveMQ Cloud Serverless dashboard.

Creating a HiveMQ Cloud cluster

2. Create a new HiveMQ Cloud free cluster and keep the Cluster URL handy.

HiveMQ Cloud Cluster

3. Open MQTT.fx application and click on HiveMQ Cloud settings.

MQTT.fx

4. Provide a profile name for your connection. For this demo, we have used the name ‘MQTT 5 Subscription Options Testing.’

5. Add your HiveMQ Cloud cluster URL details into BrokerAddress. 

6. Click on Generate to create a Client ID on MQTT.fx. 

7. Enter your HiveMQ Cloud username and password to establish a secure connection between HiveMQ Cloud and MQTT.fx.

8. Keep the MQTT Version value to 5.0, so you can test the MQTT 5 Subscription Options. Click on Apply.

9. Enter your Connection Profile Name on MQTT.fx and click on the Connect button.  Ensure you see the green Connect icon glowing in the top-right corner.

MQTT.fx Subscribe

Testing MQTT 5 ‘No Local Option’ 

1. Create a topic on MQTT.fx after you connect your broker. For this demo, we have used ‘livingroom/sensor1/temperature’ and checked the ‘No Local’ checkbox available on the right-hand corner.

2. Click on Subscribe.

MQTT.fx Subscribe

3. Click on the Publish tab and add a payload message. For this demo, we used a text-based payload called ‘22.8’.

MQTT.fx No Local Option

4. Click on Publish and switch back to the Subscribe tab to ensure no messages are sent.

MQTT 5 No Local Subscription Option

The above steps demonstrate publish/subscribe with ‘No Local’ subscription option enabled. Now, let’s subscribe to the topic without the ‘No Local’ subscription option enabled.

1. Create the topic  ‘livingroom/sensor1/temperature’ and keep the ‘No Local’ checkbox unchecked. Click on Subscribe.

Now, let’s subscribe to the topic without the ‘No Local’ subscription option enabled

2. Click on the Publish tab and add a payload message. For this demo, we used a text-based payload called ‘42.’

Click on the Publish tab and add a payload message. For this demo, we used a text-based payload called ‘42.’

3. Click on Publish and switch back to the Subscribe tab to ensure the payload message ‘42’ is sent.

Click on Publish and switch back to the Subscribe tab to ensure the payload message ‘42’ is sent.

Testing MQTT 5 ‘Retain As Published’ 

1. Create a topic on MQTT.fx after you connect your broker. For this demo, we have used ‘livingroom/sensor1/humidity’ and checked the ‘Retain As Published’ checkbox available in the right-hand corner.

2. Click on Subscribe.

Testing MQTT 5 ‘Retain As Published’

3. Click on the Publish tab and add a payload message. For this demo, we used a text-based payload called ‘55’ and select “Retained”

Click on the Publish tab and add a payload message. For this demo, we used a text-based payload called ‘55’ and select “Retained”

4. Click on Publish five times and switch back to the Subscribe tab to ensure the messages have been sent. Note that all messages are marked as retained. This indicates that the “retain” tag is still enabled in the message header. 

Testing MQTT 5 ‘Retain As Published’

Try and experiment with other MQTT 5 Subscription options, and let us know how it went. Get in touch with us or read our documentation if you need help setting up HiveMQ Cloud or try HiveMQ Enterprise.

Conclusion

MQTT 5 subscription options provide fine-grained control over message delivery, allowing for more efficient and flexible MQTT implementations. By understanding and utilizing these options, developers can create more sophisticated and optimized MQTT-based applications.

HiveMQ Cloud and MQTT.fx serve as excellent tools for experimenting with these options and gaining hands-on experience with MQTT 5 features. As you continue to explore MQTT, remember that these subscription options can significantly enhance your messaging patterns and solve complex scenarios in distributed systems.

Jens Deters

Jens Deters is the Principal Consultant, Office of the CTO at HiveMQ. He has held various roles in IT and telecommunications over the past 22 years: software developer, IT trainer, project manager, product manager, consultant, and branch manager. As a long-time expert in MQTT and IIoT and developer of the popular GUI tool MQTT.fx, he and his team support HiveMQ customers every day in implementing the world's most exciting (I)IoT UseCases at leading brands and enterprises.

  • Contact Jens Deters via e-mail
HiveMQ logo
Review HiveMQ on G2