MQTT

What is MQTT and How is it Used?

MQTT (Message Queuing Telemetry Transport) is a lightweight, publish-subscribe network protocol that transports messages between devices. It’s designed for minimal bandwidth usage and high reliability, making it ideal for IIoT (Industrial Internet of Things) applications. MQTT works especially well in scenarios where many devices need to communicate efficiently and consistently.

Its simplicity, combined with robust message delivery options (QoS levels), makes it a go-to protocol for real-time, scalable IIoT solutions.

Publisher Client, Subscriber Client, and Broker

  • Broker:

    The broker is the core of the MQTT system. It acts as the central server that receives messages from publishers and routes them to appropriate subscribers. It ensures messages are delivered reliably and according to the specified Quality of Service (QoS) level. A broker hosts topics (see topic section below) where messages can be exchanged.

    Examples of commonly used MQTT brokers include:

    • Mosquitto – Lightweight and widely used for small to medium deployments
    • EMQX – High-performance broker for large-scale enterprise use
    • HiveMQ – Commercial-grade broker with advanced scalability and monitoring tools

    Note: An MQTT broker is required to exchange messages over MQTT. This infrastructure is not provided nor managed out of the box by Factry.

  • Publisher Client:

    The publisher sends messages to a specific topic on the MQTT broker. It doesn’t need to know who receives the message; its job is simply to send data. For example, a temperature sensor may publish updates to the topic factory/line1/temperature.

  • Subscriber Client:

    Receives messages from a topic it has subscribed to on the MQTT broker. It only receives messages relevant to that topic. For example, an MQTT collector can read messages from the topic factory/line1/temperature.

Topic

A topic is a string used by the broker to filter and route messages. It serves as a logical communication channel between publisher and subscriber clients. Topics are hierarchical, separated by forward slashes /, allowing granular control over message routing and subscription.

Examples:

  • factory/line1/temperature – A message published here can represent the temperature reading from a sensor in a production line of a factory.

  • factory/line1/power – A message published here can represent the power reading from a sensor in a production line of a factory.

Subscribers can use wildcards to listen to multiple topics at once:

  • + (single level wildcard): factory/+/temperature matches all items underneath factory where a subitem temperature exists, e.g. it matches all lines in the example
  • # (multi-level wildcard): factory/# matches all items and subitems underneath factory on multiple levels, e.g. it matches all lines and sensors like temperature and power in the example

Topics enable highly organized and flexible communication in MQTT systems.

Quality of Service (QoS)

MQTT offers three levels of QoS (Quality of Service) to control the guarantee of message delivery between the sensor (publisher) and the MQTT collector (subscriber):

  • QoS 0 – At Most Once:

    The message is sent once from the publisher to the broker, with no acknowledgment that it was received by the broker nor the subscriber. Hence there is no retry mechanism. This is the fastest and most efficient level, but delivery from the publisher to the subscriber is not guaranteed.

    Example: The temperature sensor (publisher client) only sends a message once to the broker, to be received by the MQTT collector (subscriber client). If there is a connection interruption in between either the sensor and the MQTT broker or either the MQTT broker and the MQTT collector, messages may be lost.

  • QoS 1 – At Least Once:

    The message is guaranteed to arrive, but it may be delivered more than once if acknowledgments are lost. The subscriber must handle potential duplicates. Suitable for applications where occasional duplicates are acceptable.

    Example: The temperature sensor (publisher) sends a message to the broker, to be received by the MQTT collector (subscriber). When the MQTT collector receives the message, it sends an acknowledgment back to the broker, which is also forwarded to the temperature sensor (notifies both the MQTT broker and the temperature sensor that the message was received by the MQTT collector). If the acknowledgment message is not received by the temperature sensor e.g. because of a connection interruption, it resends the corresponding message until it is received successfully.

    Note: Often overlooked is that for QoS 1 to work properly, the publisher needs to have a memory/storage buffer implementation to keep track of the messages for which no acknowledgment was received yet.

    Note: If the message contains a timestamp, which is then used by the MQTT collector to assign timestamps to data points, duplicate messages will overwrite the same data point, causing no issues. If there is no timestamp in the message, the MQTT collector uses the time of receipt, which can result in inaccurate data points especially when acknowledgments fail and messages are buffered.

  • QoS 2 – Exactly Once:

    Similar to QoS 1, but the message sent by the publisher is guaranteed to arrive only once at the subscriber, through a handshake process (multiple messages back and forth). This is the most reliable but also the most resource-intensive QoS level.

Important: It is advised to use QoS 1 or higher if no data points may be lost. Ensure the publisher has a buffer implementation to keep track of which messages were acknowledged to be received and which were not.

Persistent Sessions

In MQTT, a Persistent Session (also called a non-clean session) allows a subscriber to retain its session state across disconnects.
This means the MQTT broker keeps track of the client’s subscriptions and stores any unreceived QoS 1 or QoS 2 messages while the client is offline. QoS 0 messages are never queued, even with a persistent session.

Key Features:

  • The broker stores the subscriber state (last message processed by the subscriber) and any messages that were published while the client was offline.
  • When the subscriber reconnects, the broker resumes the session by handing over the next message where the subscriber left off.

Note: A persistent session only works if all messages from the sensor (publisher) reach the broker and the broker is configured to persist messages for the according QoS level (some brokers support persistent sessions on QoS 0, where officially it is supported for only Qos 1 and QoS 2). Persistent sessions can increase the load on the broker due to the size of the retained message queues.

MQTT Specifications

MQTT itself does not define a strict message specification β€” it supports any payload format.

At Factry, we provide collectors for two commonly used payload formats:

  • Generic JSON: A flexible format designed for parsing structured JSON messages
  • Sparkplug B: A well-defined binary format optimized for efficiency and state management

1. Generic JSON Structure

In MQTT communication, messages are often formatted using a Generic JSON Structure to maintain consistency, readability, and compatibility across various clients and platforms.

This structure typically includes metadata like device ID, timestamp, and sensor readings.

Key features:

  • Flexibility of message structure

Handling Generic JSON Messages

2. Sparkplug B

Sparkplug B is designed specifically to have a standardized message format that is efficient and highly performant in use.

Key features:

  • Binary payload encoding ensures efficiency, though it complicates debugging as messages must be decoded.
  • State management – tracks client birth/death certificates to monitor online/offline status
  • Standardized message types for metrics, diagnostics, and commands

Handling Sparkplug B Messages

Extra Information

For a better understanding of MQTT, check out the following articles:

MQTT Essentials

MQTT Essentials - Publish & Subscribe Architecture

MQTT Tutorials – Introduction to Publish/Subscribe Pattern