MQTT vs DDS is a question that shows up in robotics, automotive and industrial automation projects, where some systems need microsecond-level determinism on a local network and others need to get data from many sites into the cloud. Both are publish/subscribe, but MQTT relies on a central broker while DDS lets participants discover each other and exchange data directly. This guide compares the architectures, real-time guarantees and typical deployments, and shows where brokered MQTT to a cloud service is the practical choice.
Two Philosophies of Publish/Subscribe
MQTT is brokered. Every client opens a connection to a broker, publishes to topics and subscribes to topic filters, and the broker routes each message. Clients do not know about each other. This makes the network topology simple: devices only need an outbound connection to one well-known endpoint, which works through NAT, firewalls and cellular networks. For a refresher on the broker's role, see what an MQTT broker does.
DDS (Data Distribution Service) is an Object Management Group standard for data-centric, brokerless publish/subscribe. Participants in a DDS domain discover each other, usually over UDP multicast on the local network, and exchange data directly using the DDSI-RTPS wire protocol. Topics are strongly typed with an IDL-defined data structure, and each reader and writer declares quality-of-service policies that DDS matches automatically. DDS is the middleware underneath ROS 2 and is common in defense, aerospace, medical devices and some automotive and energy systems.
MQTT vs DDS at a Glance
| Aspect | MQTT | DDS |
|---|---|---|
| Standard | OASIS MQTT 3.1.1 and 5.0 | OMG DDS with DDSI-RTPS wire protocol |
| Architecture | Central broker | Brokerless, peer-to-peer within a domain |
| Discovery | None; clients know the broker address | Automatic participant and endpoint discovery |
| Transport | TCP, TLS, WebSocket | Mostly UDP (unicast and multicast), also shared memory and TCP in some implementations |
| Data model | Topic string plus opaque payload | Typed topics defined in IDL, keyed instances |
| QoS | 3 delivery levels plus retained and sessions | Many policies: reliability, durability, history, deadline, liveliness, ownership and more |
| Latency focus | Low, but through a broker hop | Very low, direct peer delivery |
| Network scope | LAN, WAN, internet, cellular | Primarily LAN; WAN needs routing services |
| Footprint | Very small clients, runs on microcontrollers | Heavier; micro-profiles exist for embedded targets |
| Security | TLS plus broker authentication | DDS Security plugins for authentication, access control, encryption |
| Typical home | IIoT telemetry, remote sites, cloud integration | Robotics, vehicles, real-time control systems |
Architecture: Broker vs Data Bus
The broker in MQTT is both a strength and a cost. It gives you a single place to authenticate clients, enforce quotas, see every topic and connect the cloud. It also adds one network hop and is a component that must be available. A managed broker shifts that availability work to the provider.
DDS removes the middle hop. Writers send directly to matched readers, which cuts latency and avoids a central dependency on the local network. The price is complexity: discovery traffic grows with the number of participants and endpoints, multicast must be allowed on the network, and crossing subnets, NAT or the internet requires extra routing services. DDS is excellent inside a robot, a vehicle or a cell; it is awkward across hundreds of remote sites.
Real-Time Guarantees and QoS
DDS QoS is far richer than MQTT QoS. A DDS writer can declare that it updates a topic at least every 10 milliseconds (deadline), that late joiners should receive the last N samples (durability and history), that a reader should be notified if a writer goes silent (liveliness), or that only the highest-strength writer should be heard (ownership, useful for redundant sensors). DDS matches compatible readers and writers and reports incompatibilities. Combined with UDP and shared memory transports, this makes DDS a good fit for control loops and sensor fusion.
MQTT keeps it simpler. QoS 0, 1 and 2 define delivery guarantees, retained messages give late joiners the last value, persistent sessions buffer for offline subscribers and Last Will signals ungraceful disconnects. MQTT 5 adds message expiry, which helps discard stale commands. These are the features most telemetry and supervisory applications actually need. For a refresher, see MQTT QoS levels explained.
Neither protocol makes a system hard real-time by itself. Determinism also depends on the operating system, network and hardware. But DDS gives you the vocabulary to specify timing behavior, and MQTT does not try to.
Robotics vs IIoT
In robotics, ROS 2 made DDS the default. Nodes on the same robot or local network publish sensor data, transforms and commands to each other with low latency, and discovery means you can start nodes in any order. That is DDS doing exactly what it was designed for.
In industrial IoT, the requirements look different. Data must flow from PLCs, machines and gateways in many plants to supervisory systems, historians and cloud applications, through firewalls and over WAN links. Integrators expect a Unified Namespace organized by ISA-95 levels, and many devices already speak MQTT or Sparkplug B. Here a broker is an advantage, because it gives every site one outbound connection and one place to look for data. The MQTT Sparkplug B and Unified Namespace guide explains that model.
Bridging DDS to MQTT: A ROS 2 Example
The common pattern is DDS inside the machine and MQTT outward. A small ROS 2 node subscribes to local DDS topics and publishes selected, downsampled data to an MQTT broker. The example below forwards battery state from a robot to ConnectMQ.
import json
import ssl
import time
import paho.mqtt.client as mqtt
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import BatteryState
class BatteryToMqtt(Node):
def __init__(self):
super().__init__("battery_to_mqtt")
self.last_sent = 0.0
self.mqtt = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id="YOUR_CLIENT_ID")
self.mqtt.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
self.mqtt.tls_set(cert_reqs=ssl.CERT_REQUIRED)
self.mqtt.will_set("connectmq/site1/fleet/robot7/status", "offline",
qos=1, retain=True)
self.mqtt.connect("broker.connectmq.com", 8883, keepalive=30)
self.mqtt.loop_start()
self.mqtt.publish("connectmq/site1/fleet/robot7/status", "online",
qos=1, retain=True)
self.create_subscription(BatteryState, "/battery_state",
self.on_battery, 10)
def on_battery(self, msg: BatteryState):
now = time.time()
if now - self.last_sent < 5.0: # downsample to one message per 5 s
return
self.last_sent = now
payload = json.dumps({
"voltage": round(msg.voltage, 2),
"percentage": round(msg.percentage, 3),
"ts": int(now),
})
self.mqtt.publish("connectmq/site1/fleet/robot7/battery", payload,
qos=1, retain=True)
def main():
rclpy.init()
node = BatteryToMqtt()
try:
rclpy.spin(node)
finally:
node.mqtt.loop_stop()
node.destroy_node()
rclpy.shutdown()
if __name__ == "__main__":
main()
Two design choices make this bridge robust. It downsamples, because DDS topics can run at rates that make no sense to ship over a WAN. And it uses a retained Last Will, so fleet dashboards see the robot go offline even if the bridge crashes. For a quick experiment without credentials, connect to port 1883 with a unique client ID and use a connectmq/demo/<random-id>/ prefix on the free public MQTT broker.
Decision Checklist
- Do components need to exchange data in milliseconds on the same machine or LAN, with strict timing QoS? Use DDS there.
- Do you need data from many sites, across NAT or cellular, in the cloud? Use MQTT for that path.
- Are your devices microcontrollers, PLCs or commercial gateways? They most likely speak MQTT.
- Are you building on ROS 2? Keep DDS on the robot and bridge selected topics to MQTT.
- Do you need a Unified Namespace or Sparkplug B? That is an MQTT ecosystem.
- Do you want one place to authenticate, monitor and limit clients? That is a broker's job.
Where a Cloud MQTT Broker Fits
When the DDS world needs to talk to dashboards, historians, mobile apps and other sites, a cloud MQTT broker is the practical meeting point. ConnectMQ offers MQTT 3.1.1 and 5.0 over TLS, detects ISA-95 and Unified Namespace topics, decodes Sparkplug B and shows devices by ISA-95 level in its portal. It does not speak DDS itself, so a bridge node like the one above is the honest integration path. For deeper industrial context, read the industrial IoT with MQTT guide, and for protocol basics the MQTT tutorial.
Get Started with ConnectMQ
Keep DDS where determinism matters and send the data that the rest of the business needs to a managed broker. Create a free Serverless broker at app.connectmq.com, no credit card required, run your bridge node and watch the topics appear in the live explorer.
Frequently Asked Questions
Is DDS faster than MQTT?
On a local network DDS usually has lower latency because data goes directly from writer to reader without a broker hop. Across WAN and internet links that advantage fades, and MQTT is easier to route.
Can DDS work over the internet?
Not easily on its own, since discovery relies on local multicast and direct peer addressing. Routing services and relays exist, but most teams bridge selected data to MQTT instead.
Does ROS 2 support MQTT?
ROS 2 uses DDS by default. You can connect it to MQTT with a bridge node, either a community package or a small custom node like the example in this article.
Should I use DDS or MQTT for IIoT?
For plant-to-cloud telemetry, supervisory data and Unified Namespace architectures, MQTT is usually the better fit. DDS suits real-time control inside machines and cells.



