MQTT Protocol Detailed Explanation: A Comprehensive Guide from Basics to Industrial Applications
Updated: Oct 12

A remote pump can send a temperature value to a maintenance dashboard without giving the dashboard direct access to its PLC. MQTT is one way to move that value: a client publishes a message to a broker, and authorized subscribers receive messages on matching topics. The protocol does not define what a pump value means, read a Modbus register on its own or make a cellular link reliable.
Before choosing MQTT settings, identify the source of each data point, the publisher, the broker, the subscribers and the decision made from the data. The MQTT 5.0 specification defines the protocol behavior; equipment features and application semantics still need model-specific and project-specific checks.
Introduction
MQTT is a client/server publish-and-subscribe messaging protocol used in connected-device and industrial applications. It separates the producer of a message from the applications that receive it: clients communicate through a broker using topic names and subscription filters. This can suit telemetry and event distribution where bandwidth, endpoint resources and operations matter. MQTT does not define the meaning of an industrial measurement, acquire PLC data on its own or make an unavailable network reliable. Its suitability depends on the complete data path and the consequences of loss, duplication or delay.
This guide moves from the protocol's purpose and message flow to broker architecture, topics, delivery semantics, session state and MQTT 5 features. It then covers transport security, broker setup, client-library examples, protocol selection and an illustrative industrial integration stack. The pump telemetry path provides a concrete running example alongside applications in transport, manufacturing and infrastructure. Tables and code illustrate design choices; their assumptions must be checked against the selected library, firmware, broker and installation.
MQTT 3.1.1 and MQTT 5.0 remain distinct protocol versions with different properties and diagnostics. The OASIS standards describe their behavior; a platform's support for the newer version must still be verified. Select features for a documented application need, such as explaining a rejected subscription or expiring obsolete data. Neither a version number nor an IoT label establishes global adoption, a guaranteed benefit from edge AI or an automatic fit for a 5G deployment.
What is the MQTT Protocol?
MQTT developed in the context of remote telemetry and now supplies a binary client/server messaging protocol for many connected applications. A client establishes a connection to a broker, which matches publications with authorized subscriptions. The standard requires an ordered, lossless, bidirectional underlying connection; TCP/IP is commonly used, with TLS where configured. A cellular or satellite access path must provide the appropriate service, and MQTT-SN is a separate protocol for constrained networks. MQTT's fixed header starts with a control byte followed by a variable-byte Remaining Length; the complete packet also depends on its variable header, properties, topic and payload. Small messages can have modest overhead, but a fixed total byte count or universal comparison with HTTP is not justified.
MQTT's Design Philosophy & Key Features
MQTT combines a decoupled messaging pattern with explicit delivery and connection-state mechanisms. Each mechanism solves a particular part of the communication task:
Publish/subscribe: producers send to concrete topic names and consumers subscribe to filters; they need not maintain direct connections to one another.
QoS: delivery levels 0, 1 and 2 specify protocol delivery semantics with different state and exchanges. They do not guarantee that a downstream business operation executes once.
Sessions: a supported session policy can retain subscriptions and pending QoS state across reconnects, subject to version, expiry, storage and broker limits.
TLS integration: supported TLS can protect a client-to-broker transport when trust and peer identity are verified. That is separate from end-to-end payload protection and application authorization.
MQTT generally uses a long-lived, ordered connection rather than the base CoAP datagram model. MQTT 3.1 is a legacy version; MQTT 3.1.1 became an OASIS Standard in 2014, and MQTT 5.0 in 2019. MQTT 5 adds properties, more diagnostic reason codes and finer session controls. These changes provide tools for implementation and diagnosis, rather than a fixed improvement in reliability or development speed.
Why MQTT Is Useful in IoT/IIoT
A compact messaging design can be useful when a device sends small readings or events through a constrained access link. Actual memory use includes the client library, operating environment, TLS buffers, queued messages and the application. For an illustrative street-light system, gateways might publish status to a maintenance service and accept separately authorized commands. Measure reporting traffic, recovery, queue growth and command behavior on that installation; MQTT does not establish a particular node count, memory footprint, data volume, availability or saving relative to another design. The deployment remains responsible for fresh values and safe local behavior.
Basic Principles and Workflow of MQTT
A publisher sends an Application Message to a concrete topic. A subscriber independently requests one or more topic filters, and the broker routes matching publications according to the subscription, permissions and delivery settings. Retained storage, session persistence and offline queues are additional mechanisms or implementation choices. This event-distribution pattern can reduce direct producer-to-consumer coupling, while request/response interactions may still be implemented at the application layer when required.
Publish/Subscribe Pattern and MQTT Message Flow
The key distinction is between a topic name used for a publication and the filters used for subscriptions. A broker owns the matching and delivery service; the protocol does not require a particular queue product, topic-tree data structure or matching algorithm. Trace the actual exchanges in this order:
Connect: the publisher and subscriber establish their own authenticated broker connections using supported protocol versions and client identifiers.
Subscribe: the receiving client sends SUBSCRIBE with its filters and requested maximum QoS, then checks SUBACK and the granted result.
Publish: the sending client issues PUBLISH with a concrete topic, payload, QoS and retain choice. It checks the applicable acknowledgment and any MQTT 5 failure reason.
Deliver: the broker matches authorized subscriptions and forwards messages under their applicable QoS and options. The receiving application separately validates and processes the payload.
Fan-out lets a vehicle gateway, for example, publish an engine-speed reading to a topic while an authorized dashboard and analytics service receive the same subject independently. This is an illustrative integration pattern, not a measured synchronization result. Capacity depends on clients, filters, message sizes, rates and broker resources. A single broker can also be a service dependency; whether redundancy, clustering or another recovery design is needed follows from the availability requirement and the product's actual behavior.
Map One Data Point Through the Broker
Suppose a gateway reads a pump temperature from a documented PLC register. It timestamps and validates the value, publishes it on site1/pump01/telemetry/temperature, and a monitoring service subscribes to that topic. The sensor, PLC and Modbus guide explains why a protocol gateway must know the PLC's register map. A router that only forwards IP packets does not automatically perform Modbus-to-MQTT conversion.
Follow the actual packet and subscription path
The publisher first connects to the broker with a client identifier and negotiated settings, then sends PUBLISH packets to a topic. A subscriber connects separately and sends SUBSCRIBE with one or more filters; the broker matches publications and forwards them subject to authorization and requested QoS. The broker does not manufacture a PLC value. In the pump example, record the gateway's source register, payload conversion and client identity as well as the destination topic. If a dashboard shows nothing, inspect whether the value was read, published, accepted by the broker and matched by the subscription in that order.
If the router itself collects and publishes the data, use the publishing-task diagnostic when fresh messages stop.
Packet routing does not read a PLC register or translate it into an MQTT payload. Assign acquisition, mapping and publication to documented components.
Detailed Explanation of MQTT Packet Structure
A control packet contains a fixed header and, where defined for that packet and version, a variable header and payload. Remaining Length uses a variable-byte encoding, so the fixed header is not universally two bytes. CONNECT establishes a connection, PUBLISH carries an application publication, SUBSCRIBE requests filters and PINGREQ participates in keep-alive processing. A PUBLISH packet's topic, packet identifier at QoS above 0 and MQTT 5 properties affect its size. Include TCP/TLS and link overhead when estimating actual traffic instead of assigning every QoS 0 message a fixed five-byte header.
MQTT 3.1, 3.1.1, 5.0: Version Differences & Migration Guide
Compare the versions implemented at every endpoint before changing features. Version support is a property of the broker, client library and deployed firmware, while session and application compatibility require separate checks:
Version | Standardization / status | Core behavior | Important differences | Migration considerations |
|---|---|---|---|---|
3.1 | Legacy protocol; verify the exact implementation. | Publish/subscribe and QoS with legacy connection/session behavior. | Older protocol framing and capabilities differ from subsequent versions. | Inventory installed clients and broker support; plan a tested transition rather than assuming compatibility. |
3.1.1 | OASIS Standard, 2014. | Defined publish/subscribe, QoS 0–2, Clean Session and Will behavior. | Clarified standardized behavior; MQTT-SN remains a separate protocol. | Check client IDs, session policy, topic permissions and reconnect behavior on the chosen service. |
5.0 | OASIS Standard, 2019. | Properties, expanded reason codes, session/message expiry and subscription options. | Adds negotiated limits, Topic Alias and application request/response properties; no automatic bandwidth saving. | Verify supported client/broker features and interoperability before a staged deployment. |
MQTT 3.1.1 can remain appropriate for supported installed equipment, while MQTT 5 may address a specific diagnostic or lifecycle need. Inventory topic and payload contracts, authentication, ACLs, session state and client/broker versions first. Where a broker supports both versions, test their actual interaction and feature limits, then migrate representative clients in stages. Observe rejection reasons, stale data, duplicates and application results; do not make a percentage saving the acceptance criterion without a measurement method.
MQTT Application Scenarios in IoT (Modbus/MQTT/OPC UA Integration Explained)
MQTT can connect data-producing applications with wider consumers, but a collector or gateway must perform any required field-protocol integration:
Modbus/MQTT: an identified collector reads the documented registers, interprets types and scaling, then publishes a defined payload and topic. A wind-turbine example could use this path for condition data, with timing and data quality tested for the site.
OPC UA/MQTT: use components that document the relevant OPC UA and MQTT roles and a compatible data mapping or PubSub transport profile. Verify application models, security and certificate trust separately; common transport does not imply automatically shared certificates.
MQTT-SN: evaluate it as a separate protocol with its own constrained-network features and gateway requirements. Topic identifiers and different transports are not features automatically added to a standard MQTT 3.1.1/5 client or evidence of a fixed radio-byte saving.
Detailed Understanding of MQTT Protocol Architecture
A common deployment carries MQTT over TCP/IP, with a configured TLS listener for protected transport. Ports 1883 and 8883 are conventional examples, not proof of the active listener or its security. WebSocket transport may be available in particular implementations. The application still needs a broker address, usable access path, suitable identity and a documented payload contract. A network router may supply packet forwarding while another component implements the MQTT client.
Internal Implementation of the Publish/Subscribe Model
The broker maintains subscription state and matches incoming topic names to filters. Implementations may use trees, indexes, caches or other structures; the MQTT standard specifies observable behavior rather than a required matching algorithm or its complexity. Routing cost depends on topic structure, filters, subscriptions and traffic. Benchmark the chosen broker under the intended load and failure conditions rather than assigning every broker the same message rate.
Broker's Role, Types, and High Availability Design
Broker responsibilities:
Routing and delivery: match authorized topic filters, apply subscription settings and manage the required QoS exchanges.
Session and message state: retain the state required by the selected session policy, with documented storage, persistence, expiry and capacity limits.
Product extensions: rules, monitoring, external authentication or integrations may be offered by a specific broker. Redis, disk storage and plugin behavior are implementation choices, not MQTT requirements.
Broker deployment choices:
A single-node broker can be suitable when its capacity and recovery meet the application, whether the product is open source or commercial.
A redundant or clustered service needs documented replication, failover and state-handling behavior. Licensing labels alone do not establish session migration, lossless recovery or a particular availability percentage.
For high availability, trace client reconnects, authentication, subscriptions, queued QoS messages and retained data across the proposed failover. A load balancer, active/standby pair or broker bridge does not automatically share all of that state. An edge-to-central bridge can serve a defined local/remote messaging role, but it is not identical to cluster replication. Test a broker restart and loss of the WAN path against the selected product's supported design.
Topic Structure, Rules, and Best Practices
MQTT uses UTF-8 topic strings with slash-separated levels. Topic names and filters are case-sensitive and must obey the protocol's encoded-string restrictions and negotiated or product limits. The encoded topic-name field has a 65,535-byte protocol limit, which is not a recommended naming length. Design meaningful, maintainable names and test the actual broker's constraints.
Use + for one complete level and a terminal # for multiple levels in subscription filters, for example home/+/temp or home/#.
Publish to a concrete topic name, never a wildcard filter. Filters and topic authorization are separate decisions.
A filter beginning with a wildcard does not match a topic beginning with $. Some brokers expose operational data under $SYS; availability and permissions are product-specific.
Choose a consistent hierarchy around function, site, asset and metric, such as telemetry/site1/line2/sensor3/temp. For an illustrative warehouse application, inventory/warehouseA/shelfB/itemC/stock makes ownership and an access policy easier to document. A naming convention alone grants no permission. Keep names readable, exclude secrets, document case and versioning, and verify the permitted publish and subscribe paths rather than imposing an arbitrary character count.
Define topic names around site, asset, message purpose and ownership. Keep telemetry and commands in separate namespaces, for example site1/pump01/telemetry/... and site1/pump01/command/.... Topic names are strings used for routing, not a data schema or permission policy. Document payload fields, units, timestamp source, quality flags and versioning outside the topic name. If a measurement is missing or stale, the consumer needs a rule for that condition.
Design topic filters and permissions together
A topic is a hierarchy of levels separated by a slash. Subscribers may use + for one level or # for the remaining levels; a publisher sends to a concrete topic rather than publishing to a wildcard. Keep site and asset identifiers consistent and avoid putting secrets in names. Define an ACL for each client role: telemetry publishers, dashboard subscribers and any separate command publisher. Test a permitted filter and a deliberately forbidden one. A broad subscription such as site/# may expose more devices than an operator needs.
QoS Levels Explained (Mechanism, Performance & Selection Guide)
QoS describes delivery on an MQTT sender-to-receiver exchange. The publisher-to-broker exchange and each broker-to-subscriber exchange are separate, and the requested, granted and supported levels matter. A successful MQTT acknowledgment does not establish that a dashboard saved a value or a PLC executed a command. The following table distinguishes exchanges from application acceptance:
QoS level | Protocol delivery semantics | MQTT exchange | State / traffic considerations | Application use and risk |
|---|---|---|---|---|
0 | At most once; the receiver may not receive a publication. | PUBLISH; no MQTT acknowledgment. | Least protocol exchange state; no fixed RTT or total byte cost. | Telemetry may tolerate a missing sample when freshness and gaps are checked. |
1 | At least once; duplicate delivery is possible. | PUBLISH → PUBACK, with success/failure handling appropriate to the version. | Acknowledgment and delivery state add traffic; duplicates need an application policy. | Events may need identifiers and deduplication; PUBACK does not prove downstream processing. |
2 | Exactly-once delivery within the applicable MQTT exchange. | PUBLISH → PUBREC → PUBREL → PUBCOMP. | More state and protocol packets; four packets do not mean four fixed RTTs. | Use where the protocol guarantee is needed; business execution still needs authorization, identity and result confirmation. |
Choose QoS for each message type from the consequences of loss, duplication and delay. There is no universal default, quota for QoS 2 traffic or guarantee of zero application loss under a particular packet-loss rate. Compare fresh telemetry, alarm events and approved command requests on a representative link. Observe acknowledgments, duplicates, backlog and the receiving application's actual result when connectivity is interrupted.
Choose QoS for the Consequence of Loss or Duplication
MQTT offers QoS 0, 1 and 2. QoS 0 is a single send with no protocol-level acknowledgment. QoS 1 uses acknowledgment and may deliver a duplicate. QoS 2 uses a four-step exchange to prevent duplicate delivery within that MQTT exchange. None of these levels proves that a downstream application processed a message exactly once or that a PLC action succeeded.
Use case | Starting question | Application check |
|---|---|---|
Frequent telemetry | Can the next sample replace one missed value? | Detect gaps and stale timestamps |
Alarm or event | Is a retry needed, and can consumers deduplicate? | Give each event an ID and verify acknowledgment in the application |
Control request | Is MQTT an approved control path at this site? | Authorize the sender, reject stale requests and confirm the actual device result |
Do not choose QoS 2 as a universal safety setting. It adds exchange state and traffic, while retries, session behavior and the application's own processing still matter.
Record why a message type uses its chosen QoS and test it over the actual cellular path.
Interpret acknowledgments at the correct boundary
At QoS 1, PUBACK confirms the MQTT hop handled that publication; retransmission can cause duplicates. QoS 2 adds a handshake for exactly-once delivery in the protocol exchange, with more state and packets. Neither acknowledgment confirms that an end user's display updated or a controller action completed. Assign an application message identifier and deduplication rule if repeated processing has consequences. For telemetry, choose whether occasional loss, duplication or delayed backlog is the greater problem, then test that choice under an interrupted cellular connection.
Session Management (Persistence & Lifecycle Control)
Session behavior begins with CONNECT, the client identifier and version-specific settings. Keep the identifier stable when resuming the same logical client and unique across different active devices; sharing an identifier can cause an existing connection to be replaced.
MQTT 3.1.1: Clean Session controls whether the session is discarded or maintained under the standard and the broker's supported storage behavior.
MQTT 5: Clean Start controls whether a new session is started; Session Expiry Interval controls how long state can remain after disconnection. Clean Start false alone does not provide lasting offline state.
Keep Alive: configure and test a suitable interval. When nonzero, the server's timeout rule applies to missing control packets; it is not a universal recommended range or proof of machine health.
Message Expiry Interval: bounds the useful lifetime of a publication in MQTT 5. It is distinct from session expiry and does not replace timestamps and freshness checks at the application.
Set queue, message-size and storage limits from the reporting rate, outage duration and available memory or disk. An illustrative drone telemetry task may need to prioritize new status over an old backlog, but session persistence alone does not establish a reconnection time. Test short and long interruptions, broker restarts where relevant and expiry at reconnect. Document which state survives, what the client must re-establish and how the application identifies stale or missing data.
MQTT 5.0 has session and message-expiry controls. Their effect depends on client, broker and subscription settings. Test what remains queued while the site is offline and what is delivered on reconnect. Decide how consumers handle late messages, duplicates and ordering. For a changing process value, a delayed backlog may be less useful than a fresh reading.
Set a session lifecycle deliberately
Client ID, Clean Start and Session Expiry affect whether subscription and pending QoS state can survive a reconnect. A persistent session does not mean unlimited offline storage: broker policy, quotas and message expiry still apply. Decide how long an offline pump should accumulate messages, how the client resumes and whether the consumer needs all historical samples or only a fresh value. Test a short interruption and a longer one, with broker restart where relevant, and record the queue limits observed on the actual service.
Application and Cleanup of Retained Messages
A retained publication can store the latest retained message for its topic at the broker and supply it to matching new subscriptions under their options. It is a snapshot of the last retained publication, not proof of the current physical value. To clear retained state, publish a zero-byte payload to that topic with RETAIN set, subject to authorization. MQTT 5 Retain As Published changes the retain flag seen on forwarded messages; it is not a deletion operation. Persistence and expiry behavior depend on protocol settings and the broker, while consumers still need timestamps and validity rules.
Handle Retained Messages, Sessions and Disconnections
A retained publication stores the latest retained message for its topic at the broker and can be sent to a new subscriber. That is useful for some current-state indicators, but a retained value may be old. Include a timestamp and validity rule; avoid treating a retained command as a fresh instruction. A Last Will message can notify subscribers after an ungraceful disconnect, but it is not proof that the machine itself has failed.
Implementation and Monitoring Integration of Last Will and Testament (LWT)
A client can supply its Will topic, payload, QoS and retain choice in CONNECT. The broker publishes it under the protocol's disconnect and session conditions; MQTT 5 can also apply Will Delay. A normal disconnect, a lost connection and a resumed session can produce different outcomes. A prebuilt Will timestamp records when that payload was prepared, not necessarily when a failure occurred. Combine connection signals, last-good-data timestamps and monitoring observations where operators need process status. Monitoring integration can help detect problems but does not itself establish an availability percentage.
Treat the Will as a connection signal
A client can register a Will publication when connecting; the broker sends it if the connection ends unexpectedly under the configured conditions. Use it to flag loss of the MQTT connection, not to assert that the physical machine failed. Pair it with timestamps and an application heartbeat or data-quality rule where operators need to know whether measurements are fresh. A clean disconnect and a network outage have different Will behavior. Test both paths and ensure a delayed Will cannot overwrite a newer healthy state.
A retained value is the last retained publication, and a Will is a connection signal. Use timestamps and application evidence to establish current process state.
What are the New Features of MQTT 5.0?
MQTT 5 extends the protocol with properties, additional reason codes and finer controls for sessions, messages and subscriptions. Check which features are actually implemented and enabled in the broker and client. These tools can make a particular integration clearer or easier to diagnose, but neither a fixed feature count nor a guaranteed development-efficiency gain is a deployment result.
User Properties
User Properties carry UTF-8 key/value metadata on packet types that permit them, for example an agreed location or correlation attribute. The application must define their meaning, size and treatment; they are not automatically consumed by every intermediary or rule engine. They contribute to packet size and do not create a separate delivery guarantee outside the MQTT exchange. An application can also define metadata in its payload schema; choose and version the contract deliberately.
Reason Codes
MQTT 5 provides packet-specific reason codes and optional diagnostic information. Interpret a code in the context of the packet and operation: 0x92 means Packet Identifier not found, while 0x95 means Packet too large. Record whether CONNECT, SUBSCRIBE or a publication was rejected, then check the relevant version, permissions or negotiated limits. Logs can support diagnosis, but a code is not proof of a fixed reduction in troubleshooting time or of downstream application success.
Use MQTT 5 diagnostics without assuming every client supports them
MQTT 5 adds reason codes and properties that can help identify rejected connections, subscriptions and publications. Message Expiry Interval can bound how long a queued message remains useful; Session Expiry Interval can retain session state for a configured period. User Properties and topic aliases are optional tools, not a substitute for a documented payload schema. Verify that the broker, client library and router firmware all use a compatible protocol version and settings. Log the actual reason code before changing a firewall or credential.
Subscription Options & Advanced Filtering
Shared subscriptions use the specified shared-subscription form where supported. They distribute matching messages among members of a group, but the standard does not require a particular round-robin scheduler or a capacity multiplier.
No Local and Retain Handling affect eligible forwarding or retained-message delivery under their specified conditions. Verify that each option is valid for the subscription in use.
Subscription Identifiers can help identify the matching subscription at the receiver. Topic Alias can reduce repeated topic text only within negotiated limits and its connection/direction scope; it is not a global topic identifier.
Selected MQTT 5 features compared with MQTT 3.1.1:
Feature | MQTT 3.1.1 baseline | MQTT 5 addition | Benefit and limits to evaluate |
|---|---|---|---|
User Properties | No corresponding packet property; applications can define payload fields. | Key/value metadata on applicable control packets. | Agreed metadata may help integration; it adds bytes and needs a defined contract. |
Reason Codes | More limited acknowledgment/return-code information. | Richer packet-specific reasons and optional diagnostic properties. | Improve the evidence for a rejected operation; no guaranteed debugging-time saving. |
Topic Alias | No standard Topic Alias property. | Connection-specific aliases within limits negotiated for that direction. | May reduce repeated topic text; setup, message size and traffic pattern determine any saving. |
Shared Subscriptions | Some products offered extensions; not specified in MQTT 3.1.1. | Standardized shared-subscription behavior where supported. | Distribute eligible work within a group; scheduler, scale and failover remain product/application concerns. |
Other Features: Request-Response & Message Expiry
Response Topic and Correlation Data let applications organize a request and a corresponding response in MQTT 5. They do not implement a synchronous RPC service or guarantee that a requested operation succeeds. The applications must define authorization, identifiers, response timing and duplicate handling. Message Expiry Interval can limit delivery of obsolete queued publications, while the receiver must still reject data or commands that are no longer valid for its task.
In an illustrative factory upgrade, shared subscriptions might divide telemetry processing and Topic Alias might reduce repeated topic text. Confirm client and broker support and test the same workload before and after enabling a feature. Record message size, rate, loss/retry behavior, resource use and delivery timing. A 5G access network or a large robot fleet does not establish a particular latency, scale or percentage bandwidth saving from MQTT 5.
How to Implement Secure MQTT Transmission
Assess exposure on the access network, broker, client and application. Eavesdropping, impersonation, unauthorized topics, malicious payloads and resource exhaustion need different controls. MQTT transport protection is one part of that design; authorization, payload validation, updates, monitoring and recovery remain necessary at their own boundaries.
Encryption Mechanisms (TLS/mTLS Deployment Steps)
Configure a supported TLS listener with its actual host, port, certificate chain and accepted protocol versions. A port number or a particular TLS version does not establish a fixed handshake time.
Use a server certificate appropriate to the broker's DNS name or IP and configure trusted issuing authorities on the client. Verify the peer and the expected host name; do not disable checks to make a demonstration connect.
Where mutual TLS is required, configure supported client certificates and private keys, broker validation, identity mapping and topic permissions. Plan issuance, protected storage, renewal and revocation/replacement procedures.
Mutual TLS authenticates certificate-bearing peers through their supported trust and key configuration. It does not automatically bind a client to a hardware MAC address or grant it permission to every topic. Verify both certificate validation and the broker's identity-to-authorization mapping. Handshake duration and CPU load depend on the platform, credentials, protocol and workload; measure them on the target device instead of assuming universal values.
Authentication & Authorization (ACL Fine-grained Control)
Username/password authentication: use the chosen broker's supported credential-management mechanism over protected transport. MQTT does not prescribe one password-storage format.
External identity: JWT, OAuth or a plugin-backed identity service may be supported by a product. They are not automatic MQTT 5 features or a generic token-refresh guarantee.
Topic authorization: specify each role's permitted publications and subscriptions using the selected broker's ACL mechanism. Broker substitutions and dynamic policies are product-specific; test both allowed and deliberately denied paths.
For a healthcare-device example, transport protection and topic permissions may support an authorized monitoring path, but they do not by themselves establish legal compliance or eliminate intrusions. Validate payload types, sizes, origin and freshness, restrict exposed services and document the operating responsibilities of each component. Application replay or repeated-action risks require an application design as well as secure transport.
Best Practices & Auditing
Use distinct, managed client identities and appropriately protected credentials; disable unnecessary anonymous or broad-topic access on the actual listener.
Keep certificate and host verification enabled. Use a supported authentication design rather than adding a PSK fallback without a defined need and lifecycle.
Monitor connections, authentication/authorization failures, queue limits and operational errors using the broker's logging controls. Protect log access and avoid recording secret credentials or unnecessary payloads.
Test update, backup, recovery and credential replacement procedures for the selected broker and client software; a monitoring integration is not an availability guarantee.
Secure the Broker Path and Commission It
Use TLS where supported and required, validate the broker certificate, protect client credentials and restrict each client to the topics it needs. Separate publish and subscribe permissions; a telemetry publisher should not gain command rights by sharing a connection. The router software guide helps separate connectivity, firewall, application and management responsibilities. MQTT itself does not encrypt a connection without a secure transport configuration.
TLS, identity, topic authorization and failover require supported products and configuration. A protocol or product label alone does not prove these controls.
Setting up MQTT Broker and Client Development
Broker Setup Process
Select a broker version and deployment model supported by the operating environment, then configure its listener, identity and TLS trust before exposing it to the intended clients.
Define per-role topic permissions, session/message policies, persistence, resource limits and operational logs. Enable bridges or other extensions only where the design requires them.
Connect one known publisher and subscriber; validate the payload, granted subscription and allowed/denied topics before expanding.
Measure inflight messages, queue growth and recovery for the expected workload and outage. Treat defaults as version-specific configuration, not universal tuning values.
Configure the broker as a service, not only an open port
Record listener address and transport, certificate trust, client authentication, per-topic publish and subscribe ACLs, session and queue limits, persistence and operational logs. Plain MQTT and MQTT over TLS commonly use different ports, but the exact listener is a deployment choice. Restrict reachability from the site and avoid a public broker with anonymous write access. If high availability is required, verify how the chosen broker handles sessions, subscriptions and retained messages during failover; clustering is not guaranteed by MQTT itself.
Start with one known PLC point and one subscriber. Verify the register address, unit, timestamp and payload, then test publish, subscription and topic permissions. Disconnect the WAN, restart the client and broker in controlled tests, and compare what arrives after recovery. Inspect duplicate events, stale retained data, queue growth and cellular use. Keep PLC control and safety functions in their approved system unless a separately reviewed design authorizes an MQTT-driven action.
Commission with a four-observation trace
For one known point, capture source reading, client publish attempt, broker acceptance and subscriber receipt with timestamps. Then deny the client's topic permission and observe the broker response; restore it and interrupt the WAN to inspect reconnect, duplicate delivery and stale data. Keep the client and broker versions, TLS mode, topic, QoS and payload schema with the result. A TCP connection to the broker proves only reachability. The application acceptance is a correct, fresh and authorized value at the subscriber.
Client Development Framework Overview
Choose a client library for its protocol version, transport/TLS support, callback or event model, platform support and maintenance. Eclipse Paho supplies several implementations; their APIs and capabilities differ. Understand how the selected library runs its network loop, reports errors, persists state and re-establishes subscriptions. Concurrency, batching and connection pooling are application choices rather than a universal MQTT requirement; keep work in callbacks bounded.
Integrated MQTT Client Development
Java Integration (Eclipse Paho)
The Java example uses Eclipse Paho MQTT v3 client 1.2.5 and MQTT 3.1.1. Supply an ssl:// broker URI, a unique client identifier, credentials and a trusted JVM certificate store for the chosen broker. It demonstrates a finite publish/subscribe exchange with hostname verification, not a complete persistent-session or automatic-recovery service. A failed connection or acknowledgment must be handled by the application's supervised lifecycle.
// Eclipse Paho Java 1.2.5; MQTT 3.1.1; simulated telemetry.
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public final class MqttJavaExample {
static String required(String name) {
String value = System.getenv(name);
if (value == null || value.isEmpty()) throw new IllegalArgumentException(name);
return value;
}
public static void main(String[] args) throws Exception {
String broker = required("MQTT_BROKER_URI"); // ssl://dns-name:8883
if (!"ssl".equals(URI.create(broker).getScheme()))
throw new IllegalArgumentException("TLS broker URI required");
String topic = "demo/device01/telemetry";
CountDownLatch received = new CountDownLatch(1);
MqttClient client = new MqttClient(broker, required("MQTT_CLIENT_ID"),
new MemoryPersistence());
client.setTimeToWait(10000);
client.setCallback(new MqttCallback() {
public void connectionLost(Throwable error) {
System.err.println("Connection lost; stop and inspect recovery policy");
}
public void deliveryComplete(IMqttDeliveryToken token) { }
public void messageArrived(String name, MqttMessage message) {
if (!message.isRetained()) received.countDown();
}
});
MqttConnectOptions options = new MqttConnectOptions();
options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
options.setCleanSession(true); // This example does not resume offline state.
options.setAutomaticReconnect(false);
options.setConnectionTimeout(10);
options.setUserName(required("MQTT_USERNAME"));
options.setPassword(required("MQTT_PASSWORD").toCharArray());
options.setHttpsHostnameVerificationEnabled(true);
// Configure the JVM trust store with the broker's issuing CA.
try {
client.connect(options);
client.subscribe(topic, 1);
byte[] payload = "{\"example\":true,\"temperature\":23.5}".getBytes(StandardCharsets.UTF_8);
client.publish(topic, payload, 1, false);
if (!received.await(10, TimeUnit.SECONDS))
throw new IllegalStateException("No non-retained subscription delivery");
System.out.println("Demo MQTT exchange observed; no PLC action is implied");
} finally {
try { if (client.isConnected()) client.disconnect(); }
finally { client.close(); }
}
}
}
Handle MqttException according to the API and protocol version in use. MQTT 3.1.1 connection return codes and library error reasons are not interchangeable with MQTT 5 reason codes. In particular, do not label a library exception as an invalid-client-ID MQTT 5 result without checking the actual packet and documented code. Recovery should use a single controlled retry policy outside blocking message callbacks, with bounded backoff and shutdown handling.
Go Integration (Paho Go)
// github.com/eclipse/paho.mqtt.golang v1.5.0; MQTT 3.1.1.
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"net"
"os"
"time"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
func required(name string) string {
value := os.Getenv(name)
if value == "" { panic("Missing " + name) }
return value
}
func checked(token mqtt.Token) {
if !token.WaitTimeout(10 * time.Second) { panic("MQTT operation timeout") }
if err := token.Error(); err != nil { panic(err) }
}
func main() {
host := required("MQTT_HOST") // DNS name covered by the broker certificate.
pem, err := os.ReadFile(required("MQTT_CA_FILE"))
if err != nil { panic(err) }
roots := x509.NewCertPool()
if !roots.AppendCertsFromPEM(pem) { panic("No CA certificate loaded") }
options := mqtt.NewClientOptions()
options.AddBroker("ssl://" + net.JoinHostPort(host, required("MQTT_PORT")))
options.SetClientID(required("MQTT_CLIENT_ID"))
options.SetUsername(required("MQTT_USERNAME"))
options.SetPassword(required("MQTT_PASSWORD"))
options.SetProtocolVersion(4) // MQTT 3.1.1.
options.SetCleanSession(true)
options.SetAutoReconnect(false)
options.SetConnectTimeout(10 * time.Second)
options.SetWriteTimeout(10 * time.Second)
options.SetTLSConfig(&tls.Config{
RootCAs: roots, ServerName: host, MinVersion: tls.VersionTLS12,
})
client := mqtt.NewClient(options)
checked(client.Connect())
defer client.Disconnect(1000)
topic := "demo/device01/telemetry"
received := make(chan struct{}, 1)
token := client.Subscribe(topic, 1, func(_ mqtt.Client, msg mqtt.Message) {
if !msg.Retained() {
select { case received <- struct{}{}: default: }
}
})
checked(token)
granted, ok := token.(*mqtt.SubscribeToken).Result()[topic]
if !ok || granted == 0x80 { panic("Subscription rejected") }
checked(client.Publish(topic, 1, false, `{"example":true,"temperature":23.5}`))
select {
case <-received:
fmt.Println("Demo MQTT exchange observed; no PLC action is implied")
case <-time.After(10 * time.Second):
panic("No non-retained subscription delivery")
}
}
The Go example uses github.com/eclipse/paho.mqtt.golang v1.5.0 and MQTT 3.1.1. Its callbacks must return promptly; send work to a bounded application queue when processing is expensive. Check tokens for connection, subscription and publication errors. The example leaves automatic reconnect disabled so failure exits visibly; a long-running service must define reconnect ownership, resubscription, queue limits and application deduplication rather than assuming goroutines provide them.
Python Integration (Paho MQTT)
# paho-mqtt 2.1.0; Callback API VERSION2; MQTT 3.1.1.
import os
import ssl
import threading
import paho.mqtt.client as mqtt
connected = threading.Event()
subscribed = threading.Event()
received = threading.Event()
errors = []
topic = "demo/device01/telemetry"
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
errors.append("Broker rejected CONNECT")
connected.set()
def on_subscribe(client, userdata, mid, reason_codes, properties):
if not reason_codes or any(code.is_failure for code in reason_codes):
errors.append("Broker rejected SUBSCRIBE")
subscribed.set()
def on_message(client, userdata, message):
if not message.retain:
received.set()
def ready(event):
if not event.wait(10):
raise TimeoutError("MQTT readiness timeout")
if errors:
raise RuntimeError(errors[0])
client = mqtt.Client(
callback_api_version=mqtt.CallbackAPIVersion.VERSION2,
client_id=os.environ["MQTT_CLIENT_ID"],
clean_session=True, protocol=mqtt.MQTTv311, reconnect_on_failure=False,
)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.on_message = on_message
context = ssl.create_default_context(cafile=os.environ["MQTT_CA_FILE"])
context.minimum_version = ssl.TLSVersion.TLSv1_2
client.tls_set_context(context) # Certificate and hostname verification stay enabled.
client.username_pw_set(os.environ["MQTT_USERNAME"], os.environ["MQTT_PASSWORD"])
client.connect(os.environ["MQTT_HOST"], int(os.environ["MQTT_PORT"]), keepalive=30)
client.loop_start()
try:
ready(connected)
result, _ = client.subscribe(topic, qos=1)
if result != mqtt.MQTT_ERR_SUCCESS:
raise RuntimeError("Unable to queue SUBSCRIBE")
ready(subscribed)
info = client.publish(topic, '{"example":true,"temperature":23.5}', qos=1, retain=False)
if info.rc != mqtt.MQTT_ERR_SUCCESS:
raise RuntimeError("Unable to queue PUBLISH")
info.wait_for_publish(timeout=10)
if not info.is_published():
raise TimeoutError("Publication was not acknowledged")
ready(received)
print("Demo MQTT exchange observed; no PLC action is implied")
finally:
client.disconnect()
client.loop_stop()
The Python example targets paho-mqtt 2.1.0 with CallbackAPIVersion.VERSION2 and MQTT 3.1.1. Its network loop runs separately from the main demonstration. Do not call a blocking reconnect loop inside a callback or depend on private attributes such as reconnect_count. For asyncio integration, use the library's documented external-event-loop interface and avoid running competing loop mechanisms. A production service needs a deliberate reconnect, subscription and pending-message policy.
Client-library selection and measurement criteria:
Language | Library footprint considerations | Connection behavior to measure | Concurrency / event model | Suitable integration questions |
|---|---|---|---|---|
Java | Paho JAR, JVM and TLS/runtime memory depend on packaging and workload. | Measure DNS/TCP/TLS/CONNACK time and reconnect behavior; no fixed latency. | Paho callbacks and application-managed work; avoid blocking the network callback. | Does the selected runtime, persistence and lifecycle fit the enterprise or gateway application? |
Go | Binary, TLS state and buffers depend on build and application choices. | Check connection/subscription/publication tokens on the actual link. | Library callbacks plus bounded goroutine/channel design. | Are message handling, shutdown and recovery explicit under expected load? |
Python | Interpreter, dependencies, TLS and queues contribute to memory and deployment size. | Measure the chosen loop/API version, readiness and acknowledgment behavior. | Threaded loop or documented external event-loop integration; choose one design. | Does the supported Python/Paho version meet the prototype or deployed application needs? |
Comparing MQTT VS Other Protocols for Security and Performance
Protocol selection starts with the application interaction model and the deployed implementations. The comparison keeps messaging mode, overhead, security, performance and use-case dimensions, but none of those labels supplies a measured benchmark. Evaluate the same payload, service requirements and failure conditions when comparing actual products.
Protocol | Interaction model | Overhead considerations | Security to configure | Performance to measure | Applications and design trade-offs |
|---|---|---|---|---|---|
MQTT | Brokered publish/subscribe. | Packet version/type, topic, properties, payload, QoS and transport determine traffic. | Supported TLS, client identity and per-topic permissions; payload/application controls remain separate. | Message rate, fan-out, queueing, recovery and application freshness on the selected service. | Telemetry and event distribution; broker dependency and delivery semantics need explicit design. |
CoAP | Resource-oriented request/response in the base specification. | Datagram, options, payload and security mode affect traffic; not one fixed total byte count. | Supported protected transport or object protection and application permissions. | Application response and retry behavior on the intended constrained network. | Resource interaction for constrained deployments; compare required profiles and intermediaries. |
AMQP | AMQP 1.0 defines transport, messaging and settlement; product queue/exchange models must be identified separately. | Framing, link/session behavior, payload and transport protection affect overhead. | Supported authentication, protected transport and service-specific permissions. | Transfer, settlement, storage and recovery on the selected implementation. | Business messaging and integration; verify the required transaction and operational semantics. |
XMPP | Extensible XML streams, with messaging and presence/application extensions. | XML structure, extensions and transport affect size and parsing cost. | Supported TLS, SASL and application authorization. | Connection/stream handling, routing and application response under the real workload. | Structured messaging and extensible services; needed extensions and operating model matter. |
DDS | Data-centric publish/subscribe using selected middleware/profiles. | Data model, serialization, discovery, QoS and transport influence overhead. | Identify supported security specifications/plugins, identities and permissions; not every deployment enables them. | Discovery, distribution and timeliness with the required profiles and network. | Distributed data-sharing applications; choose and test QoS, interoperability and resource behavior. |
Choose the protocol and implementation whose documented interaction and lifecycle meet the task. MQTT can distribute telemetry, CoAP can expose constrained resources and AMQP can support a particular messaging service, but these are not exclusive product categories. A hybrid edge/central design needs an explicit mapping, delivery boundary, identity policy and failure behavior at each bridge. Compare actual application results rather than ranking protocols by invented universal throughput or latency.
Industrial MQTT Protocol Stack Architecture
The following layers describe one possible industrial implementation, not mandatory layers of the MQTT standard or automatic functions of an industrial router. Separating equipment management, data integration and network/device access can clarify who owns each operation. Interoperability and timing still depend on documented interfaces and tests of the complete installation.
EMS (Equipment Management Subsystem) Layer
An equipment-management service may observe connection state, data freshness, configuration and device lifecycle. MQTT events can be one input, alongside device inventory or a supported management service such as a documented Eclipse Hono integration. Session expiry or a Will is not proof of equipment health, and MQTT does not itself supply firmware OTA. Identify which component implements any management or update function and how it is authorized and recovered.
Gateway Driver Layer
A gateway integration layer can read a supported field interface, apply documented register types/scaling and timestamps, normalize topics and publish an agreed payload. OPC UA integration likewise requires compatible roles and mapping. Serial/Ethernet drivers, offline storage and queue capacity are capabilities to verify on the actual device and software. A packet-forwarding router does not acquire PLC values or translate protocols merely by carrying MQTT traffic.
Low-level Driver Layer
At the lower layer, a platform supplies its device/network drivers, ordered transport and, where required, TLS with peer verification. MQTT packet and QoS state are handled by the selected library and its supported storage design. An embedded system may use an appropriate lwIP and TLS integration, but power draw, buffer size and recovery depend on the full device and operating cycle. Keep the boundaries between driver, transport security, messaging state and application behavior explicit.
An illustrative manufacturing path could run from a Modbus sensor or PLC through a documented collector, a data-mapping gateway, a broker and an equipment-management or monitoring application. Identify the owner of acquisition, payload quality, network transport, topic authorization and application processing. Test fresh-data delivery and agreed outage behavior for the installed design. A layer diagram alone does not establish a reduction in downtime, a cloud cluster or support for a particular 5G network feature.
Industrial MQTT Client Development
C++ Integration (Paho C++)
// Paho C++ 1.5.3 with a TLS-enabled Paho C dependency; MQTT 3.1.1.
#include <mqtt/async_client.h>
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <string>
std::string required(const char* name) {
const char* value = std::getenv(name);
if (!value || !*value) throw std::runtime_error(name);
return value;
}
void checked(mqtt::token_ptr token) {
if (!token->wait_for(std::chrono::seconds(10)))
throw std::runtime_error("MQTT operation timeout");
}
int main() {
try {
const auto uri = required("MQTT_BROKER_URI"); // ssl://dns-name:8883
if (uri.rfind("ssl://", 0) != 0) throw std::runtime_error("TLS URI required");
mqtt::async_client client(uri, required("MQTT_CLIENT_ID"));
mqtt::ssl_options tls;
tls.set_trust_store(required("MQTT_CA_FILE"));
tls.set_enable_server_cert_auth(true);
tls.set_verify(true); // Check the broker certificate host name.
mqtt::connect_options options;
options.set_mqtt_version(MQTTVERSION_3_1_1);
options.set_clean_session(true);
options.set_connect_timeout(10);
options.set_user_name(required("MQTT_USERNAME"));
options.set_password(required("MQTT_PASSWORD"));
options.set_ssl(tls);
client.start_consuming();
try {
checked(client.connect(options));
checked(client.subscribe("demo/device01/telemetry", 1));
auto message = mqtt::make_message("demo/device01/telemetry",
"{\"example\":true,\"temperature\":23.5}");
message->set_qos(1);
message->set_retained(false);
checked(client.publish(message));
mqtt::const_message_ptr incoming;
const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(10);
while (std::chrono::steady_clock::now() < deadline) {
incoming = client.try_consume_message_for(std::chrono::milliseconds(200));
if (incoming && !incoming->is_retained()) break;
}
if (!incoming || incoming->is_retained())
throw std::runtime_error("No non-retained subscription delivery");
checked(client.disconnect());
client.stop_consuming();
} catch (...) {
client.stop_consuming();
if (client.is_connected()) { try { client.disconnect()->wait_for(std::chrono::seconds(2)); } catch (...) {} }
throw;
}
std::cout << "Demo MQTT exchange observed; no PLC action is implied\n";
} catch (const std::exception& error) {
std::cerr << error.what() << '\n';
return 1;
}
}
The C++ example targets Paho C++ 1.5.3 with a TLS-enabled Paho C dependency. Configure both trusted issuing certificates and server-host verification. It demonstrates a bounded MQTT 3.1.1 publication; its code is not a claim that zero-copy payloads or SIMD JSON processing are provided automatically. Optimize parsing and copies only after measuring the application, and preserve payload ownership and lifetime across asynchronous operations.
Java Embedded Variant (Android/IoT)
On Android or another managed embedded Java platform, adapt the Java example to the supported client library and the operating system's lifecycle and network restrictions. Choose an approved background-execution design for the application's requirements; scheduling a WorkManager task is not a guarantee of an uninterrupted MQTT connection. Handle process restarts, credentials, connectivity changes and resubscription deliberately, and test the actual platform rather than assuming desktop behavior.
Embedded C (ESP32/FreeRTOS)
/* Paho paho.mqtt.embedded-c MQTTClient-C API, single-task platform fragment.
* Build with the library's platform header (Network and Timer definitions).
* tls_network must ALREADY be connected through a platform TLS adapter that
* validates the CA chain and broker host name. Plain TCP is not sufficient.
* Caller owns that transport and its cleanup. Payload is simulated telemetry.
*/
#include "MQTTClient.h"
#include <string.h>
#include <stdio.h>
static void arrived(MessageData* data) {
MQTTMessage* message = data->message;
printf("Received %u payload bytes\n", (unsigned)message->payloadlen);
}
int publish_demo(Network* tls_network, const char* client_id,
const char* username, const char* password) {
if (!tls_network || !client_id || !*client_id || !username || !password)
return -1;
unsigned char send_buffer[512], read_buffer[512];
MQTTClient client;
MQTTClientInit(&client, tls_network, 5000,
send_buffer, sizeof send_buffer, read_buffer, sizeof read_buffer);
MQTTPacket_connectData options = MQTTPacket_connectData_initializer;
options.MQTTVersion = 4; /* MQTT 3.1.1 */
options.clientID.cstring = (char*)client_id;
options.username.cstring = (char*)username;
options.password.cstring = (char*)password;
options.cleansession = 1;
options.keepAliveInterval = 30;
int rc = MQTTConnect(&client, &options);
if (rc != 0) return rc;
rc = MQTTSubscribe(&client, "demo/device01/telemetry", QOS1, arrived);
if (rc == 0) {
char payload[] = "{\"example\":true,\"temperature\":23.5}";
MQTTMessage message = {0};
message.qos = QOS1;
message.retained = 0;
message.payload = payload;
message.payloadlen = strlen(payload);
rc = MQTTPublish(&client, "demo/device01/telemetry", &message);
if (rc == 0) rc = MQTTYield(&client, 1000);
}
int close_rc = MQTTDisconnect(&client);
return rc != 0 ? rc : close_rc;
}
The embedded C fragment uses the Paho MQTTClient-C API and expects an already connected Network supplied by the platform. That adapter must implement the required timed I/O and TLS certificate and hostname verification before MQTTConnect is called; a plain TCP Network adapter is not sufficient for this example. Provide the library's Timer/Network port and any threading definitions for the selected ESP32/FreeRTOS or other target. The shown buffers and timeout are illustrative application choices, not universal sizing or real-time guarantees. The caller owns transport cleanup.
Validate bounds, return codes, payload length, connection loss, expired credentials and application shutdown on the intended device. Exercise the outage patterns relevant to the installation and inspect buffer growth and recovery. Use memory-analysis tools on platforms they support, together with target-specific checks; neither a fixed percentage of test coverage nor one packet-loss setting demonstrates production reliability.
Summary
Advantages & Disadvantages Evaluation
Advantages:
Decoupled distribution: topic-based messaging can connect producers with multiple authorized consumers while keeping application data contracts explicit.
Delivery and lifecycle controls: QoS, sessions, expiry, retained messages and Will provide defined mechanisms; choose and test them against the task.
Implementation choice: client libraries and broker products offer several runtime and deployment options. Check maintained versions, supported features and operational fit.
Disadvantages:
Broker dependency: capacity, storage, availability and recovery need an explicit supported design.
Discovery and integration: MQTT does not define a universal device-discovery, PLC-mapping or application-schema service; add only the mechanisms the system actually requires.
Extra state and traffic: higher QoS and persistent state have costs. Measure them instead of imposing a fixed RTT multiplier or an assumed real-time threshold.
Applicable Scenarios Expansion
IoT examples include smart-home telemetry and connected-vehicle events, with permissions and freshness rules appropriate to the data.
IIoT examples include equipment monitoring and inputs to predictive maintenance when a validated analysis service exists. An MQTT-driven control path needs its own approved safety and application design.
Edge/central integration may distribute local observations to remote services over an available access path. Network slicing, analytics and a particular latency require independent support and validation; they are not MQTT functions.
Large data streams, strict timing requirements or synchronous business operations may call for another architecture or an additional service. Compare the actual requirements with tools such as streaming or RPC systems rather than declaring MQTT universally unsuitable for a data size or interaction pattern. A supported MQTT request/response application is possible, but it still needs its own timeout, result and duplicate-handling rules.
Topic Design Principles (Advanced Guide)
Use an agreed hierarchy for function, geography, site, equipment and metric; document which client role owns each publication and subscription.
Keep names readable and within actual encoded-string and product limits. MQTT 5 Topic Alias is a negotiated connection/direction feature, not a permanent substitute for the topic contract.
Treat wildcard subscriptions and ACLs separately. A broad read filter must not imply broad command-publication rights.
Version the payload and namespace deliberately, document units and identity, and define compatibility for existing consumers.
Measure matching and distribution on the chosen broker. A tidy prefix hierarchy does not establish a particular algorithm or performance guarantee.
FAQ
What is MQTT, and is it still used in industrial systems?
MQTT is a client/server publish-and-subscribe messaging standard used for connected-device and industrial data exchanges. Clients publish to topics and receive authorized matching subscriptions through a broker. Whether a maintained MQTT version and implementation suit an installation depends on its data path, resources, security and lifecycle needs, rather than a claim of universal adoption.
Does MQTT replace Modbus on the machine network?
No. A gateway may read Modbus data and publish a mapped MQTT payload, but the two protocols have different roles. Confirm the device register map and conversion behavior.
Does QoS 2 guarantee that a machine action happens exactly once?
No. QoS 2 covers the MQTT protocol exchange, not the downstream controller or business operation. Give action requests identities and verify the application result in an approved control design.
Is a retained message always the current value?
No. It is the last retained publication at the broker for that topic. Check its timestamp, quality and expiry policy before using it.
Can MQTT work over a cellular connection with changing IP addresses?
Often a client can initiate an outbound connection to a reachable broker, subject to the carrier, firewall and broker configuration. Test reconnection and queued-message behavior; MQTT does not make a weak link reliable by itself.
May a publisher send to a wildcard topic?
No. Wildcards are for subscription filters. A publisher uses a concrete topic; the broker matches it against permitted subscriber filters.
Does PUBACK prove the dashboard processed the value?
No. It confirms a QoS 1 MQTT delivery step, not the subscriber's application decision. Verify broker acceptance, subscriber receipt and displayed or stored result separately.
Which MQTT client library suits Java, Go, Python or an embedded target?
Compare a maintained library for the target language and platform with the required protocol version, TLS trust/hostname verification, network-loop or callback model, session storage and recovery behavior. Java, Go, Python, C++ and embedded C implementations have different APIs and dependencies. Start from the official component documentation and verify the exact version and target; an example is not a production-recovery design.
References
OASIS MQTT Version 5.0 — Protocol rules for QoS, sessions, retained publications, Will and MQTT 5 properties.
OASIS MQTT Version 3.1.1 — The MQTT 3.1.1 standard and its connection, session and delivery behavior.
Eclipse Mosquitto Configuration Manual — Supported Mosquitto listener, authentication, authorization, TLS, persistence and operational settings.
Eclipse Paho — Official client implementation catalog and links to component documentation.
Eclipse Paho Python Migration Guide — Versioned Python callbacks and the changes between Paho 1.x and 2.x APIs.
RFC 7252 — CoAP — The base constrained-resource request/response and datagram protocol used in the comparison.
OASIS AMQP 1.0 Overview — AMQP 1.0 layering, transport, messaging, transactions and security; distinguish this from product-specific models.
RFC 6120 — XMPP Core — The core XML-stream, authentication and channel-protection specification for XMPP.
OMG DDS 1.4 Specification — The official DDS data-centric publish/subscribe specification and its profiles/QoS context.




