MQTT Protocol: The Language of Industrial IoT
MQTT Protocol: Bridging the Factory Floor to the Cloud
Imagine 500 temperature sensors spread across a large textile plant, each sending readings every second to a cloud monitoring platform. Traditional HTTP would flood the network with oversized headers and redundant payloads. This is where MQTT shines — a lightweight messaging protocol designed precisely for this class of challenges.
MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol running on TCP/IP, designed by Andy Stanford-Clark (IBM) and Arlen Nipper in 1999 for monitoring oil pipelines over satellite links. Today it serves as the backbone of the Industrial Internet of Things (IIoT).
The Publish/Subscribe Model
Instead of the familiar Request/Response model used by HTTP, MQTT operates on a publish/subscribe pattern. The concept is simple but powerful:
- Publisher: The device that sends data (e.g., a temperature sensor)
- Subscriber: The device that receives data (e.g., a monitoring dashboard)
- Broker: The central server that receives messages from publishers and distributes them to subscribers
The publisher does not know who is listening, and the subscriber does not know who sent the message. The broker manages all routing. This decoupling means you can add 100 new subscribers without changing anything on the sensor side.
Topics: A Hierarchical Addressing System
Messages in MQTT are not sent to a specific IP address. Instead, they are published to a topic — a hierarchical text path resembling a file system:
factory/line1/motor1/temperature
factory/line1/motor1/vibration
factory/line2/pump3/pressure
Subscribers choose which topics to follow and can use wildcards:
| Symbol | Meaning | Example | Result |
|---|---|---|---|
+ |
Single level | factory/+/motor1/temperature |
All lines, motor1 only |
# |
All levels | factory/line1/# |
Everything under line1 |
Practical tip: Design your topic hierarchy carefully from the start. Changing it later in a system with thousands of devices is a nightmare. The golden rule: general to specific — site/area/device/measurement.
Quality of Service (QoS) Levels
Not all messages carry the same importance. A periodic temperature reading can be lost without consequence, but a fire alarm must arrive no matter what. MQTT offers three levels:
QoS 0: Fire and Forget (At Most Once)
- The publisher sends the message once with no acknowledgment
- Fastest and lightest — ideal for periodic sensor readings
- The message may be lost if the connection drops at the moment of transmission
QoS 1: Acknowledged Delivery (At Least Once)
- The broker sends a PUBACK acknowledgment to the publisher
- If no acknowledgment arrives, the publisher retransmits
- The message is delivered at least once, but may be delivered twice (duplication)
- Suitable for most industrial monitoring applications
QoS 2: Exactly Once Delivery
- Four-step handshake: PUBLISH, PUBREC, PUBREL, PUBCOMP
- Guarantees the message arrives exactly once — no loss, no duplication
- Slowest and most resource-intensive
- Required for critical commands: opening a valve, emergency shutdown
| Criterion | QoS 0 | QoS 1 | QoS 2 |
|---|---|---|---|
| Guarantee | May be lost | At least once | Exactly once |
| Messages exchanged | 1 | 2 | 4 |
| Network overhead | Lowest | Medium | Highest |
| Use case | Periodic readings | Monitoring data | Critical control commands |
Retained Messages
Imagine a new monitoring dashboard connects to the broker. How does it know the latest temperature if the sensor only publishes every 5 minutes? The answer: Retained Messages.
When a message is published with the retain = true flag, the broker stores the last copy. Any new subscriber immediately receives the most recent value without waiting for the next reading.
This is particularly useful for:
- Device status (online/offline)
- Last reading from each sensor
- Configuration settings
Last Will and Testament (LWT)
What happens when a sensor suddenly loses connectivity? MQTT provides the LWT mechanism: when a client connects to the broker, it registers a "will" message that is automatically published if the connection drops unexpectedly.
Client on connect: "If I disconnect, publish to factory/line1/motor1/status the message: offline"
This allows the monitoring system to detect device failures immediately.
Mosquitto Broker: The Open-Source Standard
Eclipse Mosquitto is the most popular open-source MQTT broker. It is lightweight enough to run on a Raspberry Pi:
- License: EPL/EDL (open source)
- Protocols: MQTT 3.1, 3.1.1, 5.0
- Security: TLS/SSL, password or certificate authentication
- Performance: Handles tens of thousands of concurrent connections
- Bridges: Connects multiple brokers together
In a production environment, always place Mosquitto behind a firewall and enable TLS. Unencrypted MQTT means anyone on the network can read your sensor data.
MQTT Compared to Other Protocols
| Criterion | MQTT | HTTP REST | OPC UA | AMQP |
|---|---|---|---|---|
| Model | Pub/Sub | Request/Response | Client/Server + Pub/Sub | Pub/Sub + Queue |
| Header size | 2 bytes | Hundreds of bytes | Medium | Medium |
| QoS | 0, 1, 2 | None | Yes | Yes |
| Bidirectional | Yes | No (needs WebSocket) | Yes | Yes |
| Constrained devices | Excellent | Heavy | Heavy | Heavy |
| Industry standard | IIoT, IoT | Web | Industrial automation | Enterprise messaging |
Sparkplug B: MQTT Speaking the Industrial Language
MQTT by itself does not define a data format — you can send anything. This creates a problem: every organization uses a different encoding. Sparkplug B is a specification from the Eclipse Foundation that solves this:
What Sparkplug B Adds
- Standardized topic namespace:
spBv1.0/{group_id}/{message_type}/{edge_node_id}/{device_id} - Standardized data format: Google Protocol Buffers (protobuf) — binary and fast
- Session management: NBIRTH (node birth) and NDEATH (node death) messages
- Industrial data types: Integer, float, string, datetime, arrays
- State awareness: The broker and devices always know each other's status
Practical Example
Without Sparkplug B:
factory/line1/motor1/temp → "45.2" (string? number? which unit?)
With Sparkplug B:
spBv1.0/Factory1/DDATA/Line1/Motor1 → {
metrics: [
{ name: "temperature", value: 45.2, type: Float, unit: "°C", timestamp: 1680000000 }
]
}
The difference is clear: data is structured, timestamped, and understandable by any Sparkplug B-compatible system.
Connecting Sensors to the Cloud: A Practical Scenario
Consider a small factory that wants to monitor 50 sensors remotely:
- Sensors send readings via Modbus RTU to a local gateway
- Edge Gateway converts the data to MQTT and publishes it to a local broker
- Local Mosquitto stores data temporarily and bridges it to the cloud
- Cloud Broker (such as AWS IoT Core or HiveMQ Cloud) receives the data
- Dashboard (Grafana or Node-RED) displays real-time data
The local bridge is critical: if the internet connection drops, data is stored locally and transmitted when connectivity returns. This ensures no readings are lost.
Best Practices
Network security: Always use TLS. Enable certificate-based authentication for production environments. Never expose port 1883 (unencrypted) to the internet — use port 8883 (TLS) instead.
Topic design: Start with a clear hierarchy from day one. Use lowercase English names without spaces. Avoid excessively deep topics (more than 5 levels).
Appropriate QoS: Do not use QoS 2 for everything — the overhead is unjustified for periodic readings. Use QoS 0 for frequent readings, QoS 1 for important events, and QoS 2 only for critical commands.
Summary
MQTT has become the common language between factories and the cloud. Its lightweight nature and simplicity make it ideal for thousands of sensors, while QoS levels ensure critical messages arrive reliably. With Sparkplug B, it evolves from a simple transport protocol into a complete industrial data platform. If you are building an IIoT system, mastering MQTT is not optional — it is essential.