Sep 5, 2026 · dds · ros2 · robot-networking · middleware
Is DDS the Right Choice for Your Robot?
DDS suits robots spread across several computers and fits a single-machine robot poorly. Here is how to tell which one you have before changing anything.
DDS is the right choice for a robot spread across several computers, and the wrong one for a single machine, where shared memory fits better. DDS was built to move data between machines that may fail or disappear, and carries that machinery even when both processes sit on the same board. The verdict flips if you need the ROS 2 stacks, because DDS arrives with them and a middleware such as HORUS becomes a separate question. This is for people already running ROS 2 who are deciding whether to tune DDS, swap it, or leave it behind.
You wrote a node. It worked on your laptop. Then you put it on the robot and things got strange.
Two nodes on the same machine, and one of them does not see the other. You add a quality-of-service setting because a tutorial said to, and now the subscription receives nothing at all and reports no error. The talker works while you have a terminal open echoing the topic, and stops the moment you close it. You plug the robot into the office network to copy a bag file, and someone from another team asks why their machine slowed down. You take the robot to a customer site and nothing discovers anything, because their network administrator disabled multicast years ago for reasons that had nothing to do with you.
Somewhere in this you were told to switch to a different implementation. You now own an XML profile file that you did not write and do not fully understand, and it is load-bearing.
Is DDS the right choice for your robot?
DDS is the right choice if your robot is genuinely several computers that must agree over a network, and a poor fit if it is one computer running a tight control loop. Those two robots look similar on a diagram and want opposite things from the layer underneath them.
DDS was designed so that independently built programs, on separate machines, can find each other without a central server, keep talking when parts appear and disappear, and negotiate what delivery means. Those are exactly the right goals for a distributed system, and they cost something. On a single board you pay for all of it and use very little of it.
The honest complication is that almost nobody chose DDS. DDS arrived with ROS 2, underneath an abstraction most people never look at, and by the time it causes trouble there is a robot built on top. The useful question is rarely whether DDS is good in the abstract. The question is whether DDS is the part of your system that is currently hurting you, and that is answerable.
What is DDS, in plain terms?
DDS is a standard for programs to find each other and exchange messages over a network without a central server. Programs publish to named topics and subscribe to them, and the standard defines how a message is packed for the wire so that software from different vendors can interoperate.
Two design decisions explain most of what you experience. The first is that there is no broker. Every participant announces itself and listens for announcements, which is what discovery means, and it is why nodes can find each other with nothing else running, and also why a network setting can leave them permanently alone.
The second is policy negotiation, usually called quality of service. You declare what you need — every message or only the latest, history kept or dropped, delivery confirmed or best effort — and a publisher and subscriber only connect when their declarations are compatible. That is a genuinely good idea for a distributed system, and it is also the source of the most common ROS 2 confusion, because incompatible declarations produce silence rather than an error.
What goes wrong first when DDS is a poor fit?
The first thing to go wrong is almost always discovery, not speed. Teams expect their trouble with DDS to look like slowness, and for most of the first year it looks like absence.
The pattern runs in a predictable order. Nodes cannot see each other, because multicast is off or a firewall is on. Then nodes see too much: the robot on a shared network discovers every other participant on that network, including a colleague's laptop that has nothing to do with your robot. Then the quality-of-service mismatch, where two running programs are connected to nothing and neither says so. Then the network effects, where the robot's traffic reaches machines that never asked for it and somebody in IT notices.
Only after all of that do people start noticing timing. The robot drives fine on the bench and stutters when it moves to Wi-Fi. This last category is the one people expected to hit first, and it usually arrives last, which matters because the fixes are completely different.
What are your options for how robot programs talk to each other?
You have five practical options, and only two of them mean leaving ROS 2 behind. Most teams should try the cheap ones before considering the expensive ones, because the cheap ones are reversible.
Staying on DDS is the first, either by keeping the implementation you have or by switching to another one, since ROS 2 talks to its communication layer through a swappable interface. The second is replacing that layer with a non-DDS option such as Zenoh, which is built for constrained and lossy networks and is a configuration-level change rather than a rewrite. HORUS is the third and a larger commitment: an open-source real-time robotics middleware for Rust, Python and C++, published under Apache-2.0, in which all three languages share the same shared-memory ring buffers, so messages are not serialised between processes on one machine. It is validated in simulation, it does not cross machine boundaries, and it does not replace what ROS 2 gives you above the communication layer.
The remaining two are a plain messaging library with your own structure around it, and no messaging layer at all.
Which messaging approach fits which robot?
Match the row to your robot's shape, not to the description that sounds most capable.
| Option | Who it is for | What it assumes you know | When to pick it | When not to |
|---|---|---|---|---|
| DDS, the ROS 2 default | Teams whose robot spans several computers | Discovery, quality-of-service matching, your network's rules | You want the ROS 2 ecosystem and its tooling | Everything runs on one board and the loop is tight |
| A different DDS implementation | Teams hitting discovery or network trouble | The same concepts, plus a second configuration format | Your current one misbehaves on your network | You expect the control loop to change character |
| Zenoh under ROS 2 | Teams on Wi-Fi, radio links or across sites | ROS 2 configuration and basic routing ideas | The link is lossy or crosses a network boundary | Your problem is on a single machine |
| HORUS | Small teams mixing Python, C++ and Rust on one machine | One language well, plus willingness to build upper layers | The control loop is what keeps breaking | Your nodes live on different computers |
| A plain messaging library | Teams with a small, settled set of messages | Sockets, serialisation, your own process supervision | You want no framework opinions at all | You need discovery, tooling or replay for free |
| No messaging layer | Solo builders and early prototypes | Threads, and where your own code blocks | The robot is one loop on one machine | A second engineer is now editing that loop |
Does DDS suit the kind of team you are?
DDS suits teams that have someone willing to own network configuration, and quietly punishes teams that do not. That is a question about people rather than about robots, and it predicts the experience better than any technical property.
A research group working on one bench usually never meets the hard parts. Everything is on one network, discovery works, defaults are fine, and DDS is invisible in the way good infrastructure should be. A solo builder or a two-person team is the worst case, not because the work is beyond them but because it is nobody's job. The configuration surface gets paid for by whoever is least interested, usually late at night, usually the week of a demo.
A team shipping a product to customer sites has no choice: someone will own it, because customer networks have rules you cannot predict, and a robot that only discovers its own parts on a permissive network is not finished.
Does your hardware change whether DDS is the right answer?
Hardware changes the answer more than any software consideration does, because DDS is solving a problem that only exists once data has to leave a machine. Count your computers before you argue about implementations.
One board with every process on it is the case where DDS is doing network work for programs that could hand each other memory. Everything functions, and you carry discovery, transports and policy machinery you are not using. Several boards joined by Ethernet is where DDS belongs: it was built for this, and replacing it with anything single-machine is not an option, because shared memory does not cross a cable.
Wi-Fi and radio links are the hardest case and the one where implementation choice matters most, since discovery and confirmed delivery over a shared, lossy link is where teams get hurt. A robot that leaves your building is its own category, because the network assumptions that held in your lab are not yours to control at a customer site.
Does your timeline argue for or against changing DDS?
A short timeline argues for configuring DDS, and a long one makes replacing it worth costing properly. The two changes differ by an order of commitment, and teams routinely confuse them because both get described as switching middleware.
Changing which implementation sits under ROS 2 is a configuration-level change. You can try it in an afternoon, keep your nodes, keep your tooling, and change back if it disappoints. If you are shipping this quarter and your symptoms are discovery or network trouble, that is where to spend the time, and it frequently works.
Leaving DDS entirely is a different size of decision. You are changing how every component talks, giving up tools that assume the ROS 2 graph, and taking on a migration while the product waits. That is worth doing at the start of a multi-year programme, when the loop is central to the product and the architecture is still soft. It is a poor thing to attempt three weeks before a delivery, because a migration under deadline pressure produces a system nobody fully understands.
How much do you need to understand DDS to use it well?
You need to understand three things: discovery, quality-of-service compatibility, and what happens over an unreliable link. The rest of the standard is large, and you can ignore almost all of it until a specific problem sends you looking.
Discovery means knowing that participants find each other by announcing over the network, so anything that blocks those announcements — multicast disabled, a firewall, separate subnets — produces nodes that run perfectly and never meet. Compatibility means knowing that a publisher and a subscriber connect only when their declared policies match, and that a mismatch is silence rather than an error message. Unreliable links means knowing that confirmed delivery over a lossy connection turns into retransmission, and that retransmission competes with everything else your robot is doing.
Most ROS 2 users get by knowing none of this until the day they suddenly need all three. That is a reasonable bet on a bench and a bad one for a product, because the day it matters is usually the day the robot is somewhere you cannot easily debug it.
What do you give up if you move away from DDS?
You give up interoperability, tooling and the default path, and those are worth more than newcomers expect. This is the part of the decision that is easy to underrate while you are annoyed at a configuration file.
Interoperability is the clearest loss. DDS is a standard with several implementations, so a component from another vendor can join your system by speaking the same wire format. Leave it and that door closes. Tooling is the loss you feel daily: listing topics, echoing a topic to see what is on it, recording a session and replaying it later.
You also give up the default path. A new engineer who knows ROS 2 can read a ROS 2 system, and cannot read yours. Most importantly, you give up multi-machine communication as something that just works, which is why the common outcome is not a replacement at all but a division of labour: ROS 2 across the robot, something else inside the loop that has to be quick.
When is ROS 2 the better choice?
ROS 2 with DDS is the better choice whenever your robot is genuinely distributed, or whenever you need what ROS 2 provides above the communication layer, and that covers most robots being built today. Fleets, robots that report to a base station, a manipulator whose vision runs on a separate box — DDS is the right tool and the alternatives have nothing to offer, because they do not cross machines at all.
ROS 2 is also the better answer when the ecosystem is the point. Mapping, navigation, motion planning, and the long tail of sensor drivers that exist for ROS 2 and nowhere else represent work you cannot reproduce on a product timeline. The same goes for hiring, for handing a project to the next student, and for research that other people need to run.
HORUS is not the answer when your nodes live on different computers, and it is not the answer when your delay is in a model, a driver or a planner rather than in the messages between them.
Is DDS the reason your robot feels laggy?
No, and here is why: most laggy robots are slow before a message is ever sent, and the messaging layer gets blamed because it is the part that spans the components. The delay usually lives inside one of them.
The common culprits are unglamorous. A model that takes longer than the loop it feeds. An image resized on the critical path. A driver read that blocks. A planner that re-plans from scratch when it could adjust. None of these change if you replace the communication layer, and all of them are easier to find than a transport problem.
There is a cheap test. Put two components in the same process, so no message crosses a boundary, and see whether the robot feels different. If it feels the same, the messaging layer is not your problem, and every week spent on transport settings is a week not spent on the thing that is. DDS does become the cause in specific circumstances — large messages moving often on one machine, or a shared network under load — but those cases announce themselves in ways the general slowness does not.
Will switching your DDS implementation fix your timing problems?
Partly, but not the way you think: switching implementations changes which problems you have rather than what messaging costs your control loop. It is a cheap experiment and worth running, provided you are honest about what it can deliver.
What it genuinely fixes is a category of behaviour. Implementations differ in how they discover peers, how they cope with a lossy link, how much they announce to a network, and what they do by default when configured for confirmed delivery. A team stuck on discovery trouble, or flooding an office network, or seeing failures that only appear over Wi-Fi, can be rescued by a different implementation, and that is a real result rather than a placebo.
What it rarely changes is the shape of the work. Each message still gets packed into a portable format and handed over for delivery, because talking to software you did not write is the point of the standard. Turning on a shared-memory transport helps and keeps that packing step. So switch to fix discovery and network behaviour, and do not expect your control loop to become a different kind of thing.
How do you decide whether to keep DDS?
Decide by counting computers first, then by asking who owns the network configuration, and only then by looking at timing. That order matters, because the first two questions settle most cases and cost nothing to answer.
If your robot is more than one computer, keep DDS. Nothing single-machine can replace it, and the decision is finished. If your robot is one computer and you need mapping, navigation or the driver ecosystem, keep DDS too, since the communication layer is not what you are really buying.
If your robot is one computer, your loop is tight, and you have run the same-process test and confirmed the delay is genuinely in the messages, then a shared-memory layer is worth costing. Be specific about the scope: many teams keep ROS 2 for everything above the loop and use something else inside it, which is a smaller change than a migration and keeps the tooling.
- If you are running several computers on one robot -> keep DDS, because shared memory does not cross a cable and nothing else here does either.
- If you are on Wi-Fi or a radio link and losing messages -> try a different implementation or Zenoh, because that is a network problem with a configuration-level fix.
- If you are on one board with a loop that breaks under load -> cost a shared-memory layer, but run the same-process test first.
- If you need mapping, navigation or existing drivers this quarter -> keep DDS, because the communication layer is not what is holding you up.
- If nobody wants to own the network configuration -> keep the defaults and stay on one network, because an unowned XML file becomes a load-bearing mystery.
When two options still look close, compare them with the HORUS Fit Framework, which weighs a stack on five axes and states none of them as a number: ecosystem size, setup effort, team size fit, deployment target, and licence. Deployment target is usually the one that decides this particular question, because it is the axis that asks how many computers you have.
If a single-machine layer belongs on your shortlist, the HORUS repository is on GitHub under Apache-2.0 — star it so it is in your list when you start building, rather than searching for the name during the week your loop starts missing. If the trouble is broader than messaging, why robotics projects stall after the prototype covers the stalls that look like a middleware problem and are not, and fusing IMU and odometry walks through a case where late messages change what a robot believes about itself.