What is the behavior of QoS1 in a clean session?

My explanation: If a client subscribes a topic with QoS 1 in a clean session, he receives every message as long as the mqtt connection status is determined as connected. Let’s assume the connection is for a few seconds not available and both sides aren’t recognized it. In this short time period, another client published a QoS 1 message to the broker successfully and the broker tries to send the message to the apparently connected client, but the message doesn’t receive the client and the broker also doesn’t receive a confirmation. Now the client is back, and the broker tries a few seconds later another delivery of the message, and now it works. The client sends a confirmation to the broker.

Am I right with this?

Hi Christian,

Welcome to our MQTT community!

When the clean session flag is set to true, the client does not want a persistent session. If the client disconnects for any reason, all information and messages that are queued from a previous persistent session are lost.

Learn more about persistent sessions from Persistent Session and Queuing Messages - MQTT Essentials: Part 7.

I hope this info helps. If you have further questions please do not hesitate to ask.

Kind regards,
Dasha from HiveMQ Team

Thanks for your answer daria!

I already knew what you wrote. I’m about something else. The question is what happens if the interrupted connection is not considered broken at MQTT and TCP level.

Hey Christian,

Thanks for the correction, I am very glad that you already have knowledge about persistent sessions.

Unfortunately, it is unclear to me, what do you mean by " if the interrupted connection is not considered broken at MQTT and TCP level.". Could you please clarify or provide an example how you make the broker achieve this state?

Thanks,
Dasha from HiveMQ Team

I put it differently: The broker sends a payload with QoS1. Is it now the case that if the broker does not receive an acknowledgement, it tries to deliver the message again after X seconds, even if the client is not disconnected?

Real world example: Let’s assume I’m in a bad WIFI network with my mobile device (MQTT client) and get practically no more data from the broker. However, the connection is not so bad that the TCP connection breaks off (mqtt keep alive is disabled in this example). The broker now sends me a payload with QoS1, which I do not receive. As I understand it, the broker should now resend the message after X seconds. That’s how I suppose it will be. I just don’t have a way to test this on a solid basis.

Unfortunately, QoS is often only explained in the context of a disconnection.

Hi Christian,

QoS level 1 guarantees that a message is delivered at least one time to the receiver. The sender stores the message until it gets a PUBACK packet from the receiver that acknowledges receipt of the message.

publish_qos1_flow

Quality of Service level 1: delivery at least once

If the receiver client is connected:
The sender uses the packet identifier in each packet to match the PUBLISH packet to the corresponding PUBACK packet. If the sender does not receive a PUBACK packet in a reasonable amount of time, the sender resends the PUBLISH packet.

If the receiver client is has PERSISTENT SESSION then the broker will be 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.

“Clean start” flag meaning:

  • –cleanStart == clean session
  • –no-cleanStart == persistent session

You have also mentioned “Unfortunately, QoS is often only explained in the context of a disconnection.” – could you perhaps give me a link, so I could take a look?

Thanks,
Dasha from HiveMQ Team

If the receiver client is connected:
The sender uses the packet identifier in each packet to match the PUBLISH packet to the corresponding PUBACK packet. If the sender does not receive a PUBACK packet in a reasonable amount of time, the sender resends the PUBLISH packet.

And if several messages have already accumulated? I would also call it “queuing”?! But you explained “queuing” is only possible in a persistemt session for offline clients.

Maybe it’s just a misunderstanding and/or I have a mental block. If I only read what I quoted from you, then I read it in such a way that what I initially wrote is correct.

Maybe it will help you if I explain my specific use case:

I have a mobile client (WiFi can be bad) which gets current machine status messages (at irregular intervals) from the broker. It must be guaranteed that the client always gets the current last message of a topic, even when initially connecting. Basically, of course, this works great with the retain flag. But of course it can happen that the client does not receive the message even though it is still connected. In this case, QoS 1 helps me. But the client is not interested in older messages, that would be practically overhead. However, a persistent connection would be deadly, because - if the client is really offline for a day or so, the next time it connects it will get a hurge number of (unnecessary) messages that will overload it. So the combination of QoS1 + retain flag + clean session seems to make the most sense to me. So I wanted to make sure that this is the right setting.

Hi christian,

the queuing happens for every client, regardless of clean or persistent session. The difference is, that the messages will be removed when a client goes offline with a clean session.

Internally the broker states messages where the broker is just waiting for the acknowledgement as “inflight”.

If the broker doesn’t get that acknowledgement, the broker will resend the message, when the client comes back online. Which is a problem with clean sessions, as the broker also removes the inflight messages when the client is offline.

So technically if a client stays online and does not send an acknowledgement it will not receive messages anymore.

Please let me know if this answer helps,
Thanks,
Dasha from HiveMQ Team

Thanks a lot Daria! Now we understand each other!

If the broker doesn’t get that acknowledgement, the broker will resend the message, when the client comes back online. Which is a problem with clean sessions, as the broker also removes the inflight messages when the client is offline.

Then why does the broker save the messages at all during a clean session? They will never be resend. Consequently, a QoS > 0 togehter with a clean session makes absolutely no sense. Due to the increased traffic, it is actually rather counterproductive. I wonder why a QoS > 0 with a clean session wasn’t excluded by the standard? Why the unnecessary extra work by the broker?

You’ve definitely helped me a lot. I’ve learned:

  • QoS and a clean session is a bad combination.
  • QoS works only if the client is technically offline (which doesn’t always have to be the case). So it doesn’t really guarantee that a message will be received. At most, it can only ensure that a message has been received.

Hey Christian,

We have discussed this with an engineer: It is unclear why this is not excluded by specification. Yet your conclusion is right: QoS other than 0 is useless for Cleansessions.

If you have further questions you are welcome to ask !
Kind regards,
Dasha from HiveMQ Team

1 Like