ounger
December 9, 2024, 10:29pm
1
How to ensure receiving messages from multiple topics in order?
Lets say I subscribe to two topics A and B and QoS 2 is given:
client.subscribeWith()
.topicFilter(“A”)
.qos(MqttQos.EXACTLY_ONCE)
.send();
client.subscribeWith()
.topicFilter(“B”)
.qos(MqttQos.EXACTLY_ONCE)
.send();
client.publishes().subscribe(SUBSCRIBED, this::onReceive);
When a publisher publishes in this order:
message MA to topic A
message MB to topic B
Will a subscriber as shown above always receive A before B?
Or is the only way setting Receive Maximum on broker and subscriber to 1?
See in MQTT 5 Reference:
If both Client and Server set Receive Maximum to 1, they make sure that no more than one message is “in-flight” at any one time. In this case no QoS 1 message will be received after any later one even on re-connection. For example a subscriber might receive them in the order 1,2,3,3,4 but not 1,2,3,2,3,4. Refer to section 4.9 Flow Control for details of how the Receive Maximum is used.
Daria_H
February 19, 2025, 11:02am
2
Hi @ounger
In MQTT, message ordering is only guaranteed within a single topic, not across multiple topics. Here’s what happens in your scenario:
1. Default Behavior (No Additional Flow Control)
Your client subscribes to both topics A
and B
with QoS 2 (Exactly Once).
The publisher sends:
MA
to topic A
MB
to topic B
The broker handles these messages separately and may deliver them in any order to the client.
The order of delivery to your subscriber depends on internal processing at the broker and the network.
Thus, the subscriber is not guaranteed to always receive MA
before MB
, even if they were published in that order.
2. Ensuring Order Across Topics
To enforce strict ordering across topics, you have two main options:
A. Use a Single Topic
Instead of separate topics A
and B
, use one topic (e.g., C
).
This way, MQTT guarantees strict message ordering within topic C
.
B. Set Receive Maximum = 1
Both the broker and the client must set Receive Maximum = 1
to ensure only one in-flight message at a time.
This prevents interleaving of messages from different topics.
This setting is not ideal for high-throughput applications because it slows down message processing.
Conclusion
If ordering across topics is critical:
Best Option: Publish to a single topic and differentiate messages using metadata.
Alternative Option: Use Receive Maximum = 1
, but be aware of performance trade-offs.
I hope this helps,
Best,
Dasha from The HiveMQ Team