I am trying to find out the reality about MQTT 3.1.1 message re-delivery for messages received by a MQTT subscriber with "at least once" (QoS 1) configuration:
- Do MQTT brokers re-deliver un-acknowledged "QoS 1" messages from subscribers?
- How much time must pass until MQTT broker re-deliver?
- Does the MQTT broker try endlessly to re-deliver an unacknowledged message?
- Are there other ways to trigger a re-delivery?
Assuming that a MQTT subscriber does not respond with a PUBACK
message to a received MQTT message, the MQTT broker needs (at least from my understanding) re-deliver the message which must be received "at least once" until the subscriber sends a PUBACK
for that message.
To get more concrete on what I am trying to achieve:
Is it a good/valid idea to postpone sending the PUBACK
until a received message was successfully persisted - effectively enlarging the QoS level until my subscribing application guaranteed that the message was processed.
And whether for e.g. persistence errors (timeouts to the database) no PUBACK
would be send which would automatically result in a re-delivery of such messages.
Thx & best regards
Do MQTT brokers re-deliver un-acknowledged "QoS 1" messages from subscribers?
From [the spec]:
So, yes, unacknowledged QOS1 messages will be redelivered but the only time the spec REQUIRES this to happen is when a client reconnects.
While you specificity state you are using MQTT v3.1.1 I believe it is worth noting that MQTT v5 expressly prohibits re-delivery other than following a reconnect:
How much time must pass until MQTT broker re-deliver?
As per the above automatic retry is not required by the spec. Some brokers may retransmit after a period of time. emqx supports this; mosquitto used to have an option but this was removed in version 1.5 with the change log explaining:.
Does the MQTT broker try endlessly to re-deliver an unacknowledged message?
The 3.11 spec does not provide any guidance (so, in theory, yes) but many brokers provide some control over this (maximum number of messages queued, max size of queue etc).
Are there other ways to trigger a re-delivery?
Yes - disconnect and reconnect.
Is it a good/valid idea to postpone sending the PUBACK until a received message was successfully persisted
There was a discussion re this on the paho-dev group a couple of months ago. Its something that is being considered in the Go v5 Client (currently that client automatically acknowledges messages).
One thing to note is that the MQTT spec does have requirements with regards to the order acknowledgments are sent. Many clients ignore this requirement (and just send the acknowledgments whenever the handler returns) but some (e.g. the HiveMQ Java client) queue up ACKs so they can be sent in the correct order.