Why architecture matters here
MQTT's architecture matters because it makes a specific set of trade-offs that are right for telemetry and device messaging and wrong for a lot of other things — and understanding those trade-offs is how you avoid misusing it. The central choice is the broker-mediated pub/sub model. Putting a broker in the middle buys enormous flexibility: you can add a new consumer of a device's data without touching the device, fan one message out to many subscribers for free, and let producers and consumers come and go independently. But it also means the broker is a shared piece of infrastructure that every message flows through — it is the thing you must scale, secure, and keep available, and it is the natural single point of failure that broker clustering exists to address.
The second defining choice is the persistent connection with tunable delivery. Keeping one TCP connection open per client, rather than reconnecting per message, is what makes MQTT cheap on power and bandwidth and what enables the broker to push messages down to a device the instant they are published — true bidirectional messaging, not polling. The keep-alive mechanism and Last Will exist because that persistent connection can die silently on a mobile network: the broker needs a heartbeat to notice the client is gone and a pre-registered 'will' message to tell everyone else. The three QoS levels then let each message choose its own reliability: a temperature reading every second can afford QoS 0 (send once, no ack — if one is lost another comes immediately), while a 'unlock the door' command demands QoS 2 (exactly-once, no duplicates).
The design tension that runs through all of it is overhead versus guarantee, and it recurs at every level: QoS 2 is reliable but doubles the round-trips; retained messages are convenient but persist state in the broker that must be managed; persistent sessions bridge offline clients but consume broker memory queuing their messages. MQTT gives you the knobs but does not choose for you, so the architecture of an MQTT system is largely a set of per-topic decisions about how much reliability and state each class of message actually needs — and getting those decisions wrong is how a protocol built for millions of cheap devices becomes expensive and unreliable.
The decoupling the broker provides is worth naming precisely, because it is the property that makes MQTT scale to fleets of millions and also the property most often squandered. Publishers and subscribers are decoupled in three independent dimensions. They are decoupled in space: a device publishing a reading knows only a topic string, never the addresses or even the existence of the consumers, so you can add a new analytics consumer or a new dashboard without redeploying a single device. They are decoupled in time: retained messages and persistent-session queues let a subscriber that was offline when a message was published still receive the current state or the buffered message when it returns, so producer and consumer need never be online simultaneously. And they are decoupled in synchronization: a publish call returns without waiting for anyone to consume, so a slow or absent subscriber never blocks a publisher. Each dimension of decoupling is what lets the fleet and the backend evolve independently, and each is quietly undone by an anti-pattern — hard-coding a consumer's identity into a topic, relying on a subscriber always being online, or making a publisher wait on an end-to-end acknowledgement it does not need. Preserving all three is what keeps an MQTT system loosely coupled enough to grow.
The architecture: every piece explained
Top row: the routing core. A publisher — a sensor, device, or backend service — sends a message tagged with a topic to the broker over its persistent connection. The broker's one job on the hot path is routing: it matches the message's topic against every active subscription and delivers a copy to each subscriber whose topic filter matches. Filters can be exact (home/livingroom/temperature) or use wildcards — + for one level (home/+/temperature) or # for a whole subtree (home/#). Each client's persistent session state — whether it connected 'clean' (fresh) or is resuming — determines whether the broker remembers its subscriptions and queued messages across disconnects.
Middle row: the semantics that make it robust. The topic tree is the hierarchical namespace; good topic design (specific, consistent, wildcard-friendly) is the schema of an MQTT system. QoS levels set delivery guarantees per message: QoS 0 is at-most-once (fire and forget, no ack), QoS 1 is at-least-once (acked, may duplicate), QoS 2 is exactly-once (a four-step handshake guaranteeing no loss and no duplication). A retained message is the last message published on a topic with the retain flag set; the broker keeps it and delivers it immediately to any client that newly subscribes, so a dashboard learns the current temperature the instant it connects instead of waiting for the next reading. Keep-alive is a heartbeat interval the client promises to speak within; if the broker hears nothing, it declares the client dead and publishes its Last Will and Testament — a message the client pre-registered to announce its own unexpected death (e.g. home/sensor7/status = offline).
Bottom rows: the efficiency and operation. The small fixed header — two bytes minimum, binary payloads of any kind — is what makes MQTT frugal on constrained links. The offline queue is what a persistent session provides: while a subscriber is disconnected, the broker buffers its QoS 1 and 2 messages and delivers them on reconnect, so a device that drops off a cellular network for a minute misses nothing. The ops strip is where an MQTT deployment lives or dies: a deliberate topic-naming scheme, a per-message QoS choice matched to need, broker scaling and clustering for fan-out and availability, authentication and per-topic ACLs so devices can only publish/subscribe where allowed, and monitoring of Last-Will 'offline' events as the fleet's liveness signal.
End-to-end flow
Follow a home-automation deployment. A temperature sensor connects to the broker with a persistent session, registers a Last Will of home/livingroom/sensor/status = offline (QoS 1, retained), and publishes home/livingroom/sensor/status = online. Every ten seconds it publishes the temperature to home/livingroom/temperature at QoS 0 with the retain flag — QoS 0 because losing one of six readings a minute is harmless, retained so the latest value is always available. A phone dashboard subscribes to home/+/temperature. The moment it connects, the broker delivers the retained message for every matching topic, so the dashboard shows the current temperature of every room instantly, without waiting up to ten seconds for the next reading. Thereafter each new reading is pushed to the dashboard the instant it is published — no polling, one connection, tiny messages.
Now a command in the other direction. The user taps 'lock the front door'. The app publishes to home/frontdoor/command at QoS 2, because locking must happen exactly once — neither lost nor duplicated (a double-command might unlock what it just locked). The QoS 2 four-step handshake (PUBLISH, PUBREC, PUBREL, PUBCOMP) guarantees the lock controller receives it precisely once even if the network hiccups mid-exchange. The controller, subscribed to home/frontdoor/command, actuates the lock and publishes home/frontdoor/state = locked retained, so the app (and any future subscriber) sees the confirmed state.
Then the sensor's battery dies mid-afternoon. Its persistent TCP connection drops, but silently — no clean disconnect. For a while nothing happens; then the keep-alive window elapses without the broker hearing the sensor's heartbeat. The broker declares the client dead and publishes its pre-registered Last Will: home/livingroom/sensor/status = offline. Because that status topic is retained, any dashboard — connected now or later — sees the sensor as offline, and a monitoring service subscribed to home/+/sensor/status fires an alert. The device announced its own death without being able to send anything, because it pre-loaded the announcement into the broker when it was healthy. That is the Last-Will mechanism doing exactly what silent-failure detection on bad networks requires.
Consider what a persistent session bought during a transient outage. Suppose the dashboard, not the sensor, briefly loses connectivity while a QoS 1 alert ('smoke detected', published to a topic the dashboard subscribes to at QoS 1) is in flight. Because the dashboard connected with a persistent session, the broker holds that QoS 1 message in the dashboard's offline queue and delivers it the instant the dashboard reconnects — the alert is not lost to a thirty-second network blip. Had the dashboard used a clean session (no state kept across disconnects) or subscribed at QoS 0, the alert published during the outage would simply be gone. This is the per-message, per-session reasoning MQTT forces and rewards: the temperature stream is fine at QoS 0 with a clean read, but a safety alert needs QoS 1 and a persistent session so the outage that is guaranteed to happen on a real network does not swallow the one message that mattered. The protocol does not make these choices; the architecture does, topic by topic, and the quality of those choices is the difference between a robust fabric and a lossy one.