“Delivered” sounds like a final state.
In distributed systems, it usually needs a destination attached to it.
Delivered where?
A sensor can successfully deliver to an MQTT broker.
The broker can successfully deliver to a subscriber.
The subscriber can fail to write the event to its database.
Or the database write can succeed while a later API call fails.
Every individual component may report its part accurately.
The business process can still be incomplete.
Delivery depends on where you stand
Consider this path:
Sensor → Broker → Local service → Cloud API → Customer system
From the sensor's point of view, delivery may be complete once the MQTT exchange succeeds.
From the broker's point of view, it may be complete after the subscriber receives the message according to the selected QoS.
From the local service's point of view, success may mean the Cloud API returned 2xx.
The customer may define success as the event being committed to its own database.
All four can use the word “delivered” and mean different things.
That is not necessarily a problem.
It becomes a problem when the boundaries are implicit.
QoS answers a specific question
MQTT QoS is useful precisely because its semantics are defined.
QoS 1 means at-least-once delivery within the relevant MQTT flow.
QoS 2 provides exactly-once delivery within that MQTT flow.
If the business requirement is “make sure this publication reaches the MQTT receiver according to those semantics”, QoS is directly addressing the problem.
If the requirement is “make sure this machine fault eventually appears in the customer's ERP system”, there are additional boundaries to account for.
The first guarantee does not imply the second.
This becomes visible during failure
When everything is healthy, the distinction can seem academic.
The sensor publishes.
The broker forwards.
The service calls the API.
Everything completes in milliseconds.
Then the cloud endpoint is unavailable for three hours.
MQTT may continue to behave perfectly inside the local environment.
The local service now has the unresolved responsibility.
Does it persist the event?
Does it retry?
Does it survive a restart?
Does it remember which events were already accepted by the cloud?
The architecture after MQTT determines whether “delivered to the broker” eventually becomes “delivered to the system that matters”.
Acknowledgements have local meaning too
An acknowledgement proves something about a particular protocol step.
It should not be treated as proof that every downstream effect is complete unless the contract explicitly says so.
This is true beyond MQTT.
An HTTP 202 Accepted means something different from 200 OK.
A successful database commit says nothing about whether an external webhook succeeded later.
A local SDK returning success may mean the event was durably persisted rather than delivered to its final destination.
Good APIs make these boundaries clear.
Use more precise language
Teams can remove a surprising amount of ambiguity by changing the question.
Instead of:
“Was the event delivered?”
ask:
“Did the broker accept it?”
“Did the subscriber receive it?”
“Was it durably persisted locally?”
“Did cloud ingestion accept custody?”
“Did the destination acknowledge it?”
The answers can then be different without anyone being wrong.
It also becomes much easier to decide where retries belong.
End-to-end status needs multiple pieces of evidence
A single MQTT acknowledgement cannot prove the full path completed if the path continues outside MQTT.
Likewise, a successful cloud ingestion call does not prove the final customer endpoint processed the event.
End-to-end visibility is usually built from evidence at several boundaries.
That may include:
- source event identity
- local persistence status
- MQTT delivery state
- cloud ingestion state
- destination attempts
- final acknowledgement
Not every system needs all of this.
But when an individual event matters, knowing which boundary succeeded is far more useful than one generic “delivered” flag.
MQTT did its job
There is an important distinction here.
When the MQTT portion succeeds and the next service fails, the correct conclusion is not that MQTT is unreliable.
MQTT did its job.
The architecture simply had another job afterwards.
That leads directly to the final MQTT article in this series: