MQTT for Embedded Agents: Protocol, QoS & Topic Design
MQTT for Embedded Agents
MQTT is the dominant messaging protocol for embedded agents because it was designed specifically for constrained devices and unreliable networks: its publish-subscribe model, tiny packet overhead, persistent sessions, and three-level Quality of Service make it the most practical choice for agent telemetry, commands, coordination, and registry traffic at the edge.
This page covers why MQTT fits embedded agents, how to select QoS levels for different message types, how to design topic hierarchies for a multi-agent deployment, and what MQTT 5.0 adds for agent use cases.
Why does MQTT fit embedded agents?
MQTT (Message Queuing Telemetry Transport) was designed in the late 1990s for monitoring oil pipelines over satellite links — exactly the constrained, intermittently connected scenario that characterises many embedded agent deployments. Its core properties align well with embedded agent requirements:
| MQTT Property | Benefit for Embedded Agents |
|---|---|
| Publish-subscribe | Decouples agents from each other; agents don’t need to know addresses of peers |
| Persistent sessions | Agent reconnects after power cycle and receives messages it missed |
| Last Will and Testament (LWT) | Broker publishes offline status on unexpected disconnect — ideal for registry presence |
| Retained messages | New subscribers immediately receive the last known state |
| Binary payload | Carry JSON, CBOR, Protobuf, or raw bytes — not constrained to text |
| Small fixed header | 2-byte minimum header; low overhead on bandwidth-constrained links |
| QoS levels | Trade-off between reliability and resource cost per message type |
| TLS transport | Standard security for production deployments |
| MQTT 5.0 properties | Message expiry, correlation IDs, reason codes — essential for agent coordination |
MQTT’s broker-mediated model means an embedded agent never needs to know the IP address or state of another agent. It publishes to a topic; any interested subscriber receives the message. This is architecturally important for scale: adding a new agent to a system does not require reconfiguring existing agents.
What are the MQTT QoS levels and when should each be used?
MQTT defines three Quality of Service levels:
QoS 0 — At Most Once (“Fire and Forget”)
The message is published once with no confirmation. It may be lost if the broker or client is unavailable at the moment of publishing.
Use for embedded agents when:
- High-frequency telemetry where losing an occasional reading is acceptable (e.g., temperature reported every second; losing one in a thousand is fine).
- Streaming sensor data where the next message will arrive shortly anyway.
- Status heartbeats complemented by retained messages (the retained message covers the case of a missed heartbeat).
Resource cost: Lowest. No acknowledgement, no retry, no persistence.
QoS 1 — At Least Once
The message is delivered at least once. The sender retains the message until it receives a PUBACK from the broker. Duplicate delivery is possible if PUBACK is lost.
Use for embedded agents when:
- Alarms and fault notifications that must reach the broker.
- Registry registration messages.
- Control commands where duplicate execution is idempotent (e.g., “set fan speed to 75%” — executing twice is fine).
Resource cost: Moderate. One round-trip acknowledgement; message is buffered until acknowledged.
QoS 2 — Exactly Once
A four-step handshake ensures the message is delivered exactly once. No duplicates, no losses.
Use for embedded agents when:
- Commands where duplicate execution would cause harm (e.g., “dispense 500 ml of chemical X” — executing twice would dispense 1000 ml).
- Financial or compliance-critical events.
- OTA update triggers (triggering an update twice could cause issues).
Resource cost: Highest. Four messages exchanged per published message; highest latency.
QoS selection summary
| Message type | Recommended QoS |
|---|---|
| Periodic sensor telemetry | 0 |
| Status heartbeats | 0 with retained flag |
| Registry presence (LWT) | 1 |
| Alarms and fault notifications | 1 |
| Idempotent commands | 1 |
| Non-idempotent commands | 2 |
| OTA update triggers | 2 |
How should topics be designed for a multi-agent deployment?
Topic design is one of the most important and often overlooked aspects of MQTT-based agent systems. A well-designed topic hierarchy enables subscription filtering, access control, and future extensibility.
Recommended structure
{site}/{zone}/{asset}/{agent-id}/{message-type}
Example hierarchy for a manufacturing facility:
plant1/line3/motor-b4/agent/telemetry
plant1/line3/motor-b4/agent/alarms
plant1/line3/motor-b4/agent/status
plant1/line3/motor-b4/agent/commands
plant1/line3/motor-b4/agent/registry
agents/registry/+ <-- all registry entries
agents/commands/motor-agent-b4 <-- commands to a specific agent
Topic design principles
-
Start specific, not generic:
plant1/line3/motor-b4/telemetryis better thantelemetry/plant1because MQTT wildcards (+and#) make it easy to subscribe to a broader namespace, but you cannot narrow a broad namespace efficiently. -
Separate telemetry, commands, status, and registry: Using different topic branches for different message types allows access-control rules to grant read-only access to telemetry without granting command access.
-
Avoid encoding state in topic names:
motor/running/speedis worse thanmotor/telemetrywith a payload field for status. Topic names should be stable identifiers; state belongs in the payload. -
Use retained messages for current state: The
agent/statusandagent/registrytopics should carry retained messages so any new subscriber immediately knows the agent’s current state. -
Namespace commands: Publish commands to a specific agent’s command topic (
{agent-id}/commands), not to a shared command bus. This prevents unintended agents from acting on commands not meant for them.
What does MQTT 5.0 add for agent use cases?
MQTT 5.0 (OASIS standard, widely deployed as of 2026) adds several features directly useful for embedded agent systems:
| MQTT 5.0 Feature | Agent Use Case |
|---|---|
| Message Expiry Interval | A command to “open valve X” expires after 5 seconds — if the agent was offline and receives a stale command, it ignores it. Critical for safety. |
| Correlation Data | Links a response to a request in request-response patterns between agents. |
| Reason Codes | Rich error reporting when a publish or subscribe fails — useful for debugging agent coordination issues. |
| User Properties | Key-value metadata attached to any message — carry schema version, trace IDs, or agent-specific context without polluting the payload. |
| Response Topic | The publisher specifies where it expects a response — enables request-response patterns over MQTT. |
| Shared Subscriptions | Multiple agent instances subscribe to the same topic; the broker distributes messages among them — enables load balancing for stateless agent tasks. |
| Flow Control | Receivers can signal their receive quota to prevent fast publishers from overwhelming slow MCU-class subscribers. |
The Message Expiry Interval is particularly important for safety-critical embedded systems. A command that arrives late should not be executed. MQTT 5.0 allows the publisher to set a TTL on the message at the broker level.
What broker should be used for embedded agent deployments?
| Broker | Strengths | Notes |
|---|---|---|
| Mosquitto | Lightweight, open source, very low resource requirement | Good for small-scale deployments; limited HA and clustering |
| EMQX | High performance, MQTT 5.0, clustering, enterprise features | EMQX Enterprise 6.2 adds native agent registry (A2A) |
| HiveMQ | Enterprise-grade, strong Sparkplug B support | Well-suited for industrial IIoT |
| VerneMQ | Open source, clustered, good scalability | Less active development recently |
| NanoMQ | Ultra-lightweight, designed for edge/gateway hardware | Runs on resource-constrained edge nodes |
For small embedded deployments (< 100 agents, single site), Mosquitto running on a gateway or Raspberry Pi is a common and practical choice. For large industrial deployments with high-availability requirements, EMQX or HiveMQ are more appropriate.
Platform example: ForestHub.ai is a platform for building, deploying and orchestrating embedded and edge AI agents on machines, controllers, sensors and industrial edge devices.
FAQ
Q: Can an MCU-class embedded agent run an MQTT client? Yes. Several lightweight MQTT client libraries are designed for MCU use: Eclipse Paho Embedded C (widely used on FreeRTOS and Zephyr), MQTT-C, and vendor-provided clients in ESP-IDF, Arduino, and STM32 HAL ecosystems. MQTT 3.1.1 is fully supported; MQTT 5.0 support on MCU clients is maturing.
Q: How does TLS add to the resource cost on a MCU? TLS adds RAM overhead for the handshake buffers (typically 8–20 KB depending on cipher suite and certificate size), CPU cost for handshake (a one-time cost per connection establishment), and ongoing per-message encryption overhead. On modern Cortex-M33 and M55 class MCUs with hardware crypto acceleration, TLS overhead is manageable. On very small Cortex-M0+ class MCUs with < 64 KB RAM, TLS may not fit without careful optimisation.
Q: What is the difference between MQTT and AMQP for embedded agents? AMQP provides richer queuing semantics and is well-suited for enterprise message bus scenarios. It is significantly heavier than MQTT and rarely implemented on MCU-class devices. MQTT is the standard for constrained embedded environments. AMQP appears occasionally at the cloud or gateway tier.
Q: What is Sparkplug B and should embedded agents use it? Sparkplug B is an open specification (Eclipse Foundation) that adds a structured payload format and a defined topic namespace on top of MQTT. It is widely adopted in IIoT and SCADA contexts. For industrial embedded agents that need to interoperate with HiveMQ, Inductive Automation Ignition, or similar platforms, Sparkplug B is worth adopting. For simpler deployments, it adds overhead without commensurate benefit.
Q: How many concurrent MQTT connections can a broker handle? A modern broker like EMQX can handle millions of concurrent connections in a clustered configuration. For a local Mosquitto broker on a Raspberry Pi, practical limits are in the thousands. For most single-site embedded agent deployments (tens to hundreds of agents), either broker is more than sufficient.
Related pages
- Agent Registry for Embedded Systems — How MQTT enables registry and discovery.
- Embedded Agent Architecture — Where MQTT fits in the agent stack.
- Industrial Embedded Agents — OPC UA + MQTT in industrial deployments.
- Glossary — Definitions for MQTT-related terms.