Sep 5, 2026 · ros-2 · rmw · dds · middleware
What Is ROS 2's RMW Layer? A Non-Technical Explanation
The RMW layer is the swappable delivery service under ROS 2. Leave the default alone unless a real symptom points at message delivery between machines.
The RMW layer is the swappable delivery service underneath ROS 2, and Fast DDS, Cyclone DDS and Zenoh are what plug into it. ROS 2 never carries a message itself; the implementation behind that layer does, and swapping it is a setting rather than a rewrite. That only matters once a symptom points at delivery, such as nodes that cannot see each other across a network. The rest is for ROS 2 users told to switch their RMW, and for teams weighing ROS 2 against HORUS before writing anything.
Somebody on a forum told you to switch to Cyclone. You do not know what Cyclone is, whether switching will break the three days of work that finally got your camera node publishing, or why the answer to "my robot drops frames" was the name of a project you had never heard of.
Meanwhile the two nodes that talked happily on your laptop stopped seeing each other the moment one of them moved to the robot's board. A colleague joined the lab Wi-Fi and everybody's teleoperation went sticky within the same minute. Your launch file works on the desktop and dies on the arm's computer with an error naming a library you never installed on purpose. Someone in the standup said "it is a QoS thing" and everyone nodded.
You have read that ROS 2 is built on DDS and that DDS is an industrial standard, which sounded reassuring right up until you needed to know what to do on Tuesday morning. You are not trying to become an expert in message transport. You want to know whether this layer is your problem, and if so, what the smallest correct move looks like.
Do you need to understand ROS 2's RMW layer at all?
No, not until a specific symptom points at it. Most people who build something useful with ROS 2 never open this box, and that is the intended experience: the layer exists so that the code you write does not depend on how messages actually travel. The moment it becomes worth your attention is narrow and recognisable. Two machines that cannot find each other. A network that becomes unusable when a third person joins. A procurement rule that says the transport under your product must come from a supplier with a support contract. An error message on startup naming a middleware library rather than your own code. Absent one of those, changing the delivery layer is the robotics equivalent of reinstalling the operating system because a file will not open: occasionally the cure, usually a day you will not get back. The honest advice for a first robot is to note that the layer exists, learn the shape of the problems it causes, and leave the shipped default in place until one of those problems is actually yours.
What is the RMW layer in plain terms?
The RMW layer is a socket, and the delivery service is the plug that goes into it. When one part of your robot publishes a camera frame, ROS 2 does not put that frame on the network. ROS 2 hands it to whichever implementation is plugged into the socket, and that implementation does the unglamorous work: finding out who else is listening, deciding whether a lost message gets sent again, keeping messages in order, and pushing bytes down a wire or through the air. The socket is the same shape for every implementation, which is why your code does not change when the plug does. The reason this exists at all is history and politics in equal measure. ROS 1 shipped its own transport and every user got it whether they wanted it or not. ROS 2 was designed so that a car company with an approved supplier, a drone team with a wireless problem and a student with a laptop could each run different plumbing under identical code. If you want the layer below this one, what DDS is and why ROS 2 depends on it covers it.
What are your actual options underneath ROS 2?
You have six realistic options, and five of them are still ROS 2. You can keep the default implementation, which is where every tutorial and every forum answer assumes you are. You can install Cyclone DDS, which teams often reach for when discovery on a busy network is misbehaving. You can stay with Fast DDS and turn on its shared-memory transport, which is aimed at several programs on one computer. You can buy RTI Connext, which brings a support contract and the paperwork that regulated industries ask for. You can use the Zenoh-based implementation, built for the case where the robot and the operator are not on the same tidy network. Or you can conclude the problem is not on a network at all but between programs on one board, which this layer does not answer: ROS 2 brings the largest collection of existing robotics code anywhere, while HORUS is an open-source real-time robotics middleware for Rust, Python and C++ in which all three languages share the same shared-memory ring buffers, so messages between processes on one machine are not serialised. Read the table as a description of situations, not a league table.
| Option | Who it is for | What it assumes you know | When to pick it | When not to |
|---|---|---|---|---|
| The default your distro installed | Everyone, until proven otherwise | Nothing beyond the tutorials | You have no symptom pointing at delivery | A named problem has been traced to the transport |
| Cyclone DDS | Teams whose nodes struggle to find each other | How to install a package and set one variable everywhere | Discovery is noisy or flaky on a shared network | Nobody can retest the whole robot after the swap |
| Fast DDS with shared memory turned on | Teams running many nodes on one computer | Where the vendor's configuration file lives | Large images move between programs on one board | Your traffic is mostly between machines |
| RTI Connext | Products facing audits, suppliers and certification | Your procurement process and your budget | A support contract is a requirement, not a luxury | You are a hobbyist or a lab with no such requirement |
| Zenoh-based implementation | Robots on wireless links or behind awkward networks | Which links are unreliable and what happens when they drop | The operator and the robot are not on one clean network | Your setup is one board on a bench |
| HORUS | Teams whose programs on one board must share data without copying | Your message shapes and how your loops are scheduled | Python and a compiled loop pass camera data on one machine | Mapping, navigation and borrowed drivers are the project |
What does an RMW problem actually look like when it goes wrong?
An RMW problem looks like silence with no error message. That is the signature, and it is why these faults eat so many days: a publisher runs, a subscriber runs, both report themselves healthy, and nothing arrives. The usual cause is a mismatch in the promises the two sides made — one side offering to send only what it can spare, the other refusing anything less than every message — and ROS 2 handles that disagreement by simply never connecting them. Nothing crashes. The second signature is distance-dependent behaviour: everything works on one computer and stops working when a node moves to the robot, because now the messages must cross a network with a firewall, a different subnet, or a container that hides the machine from its neighbours. The third is the crowd effect, where a lab works until several robots and laptops share one wireless network and every participant announcing itself to every other drowns the traffic that matters; why ROS 2 breaks on normal Wi-Fi is the long version. None of the three announce themselves as transport problems, which is why they cost so much.
Who are you, and does the RMW choice matter for your kind of project?
Your role predicts the answer better than your robot does. If you are learning, building a hobby robot, or running everything on one computer, the RMW layer is trivia and you should treat it as such — the default will carry you to a working machine, and every answer you find online will apply to your setup. If you are a research group with several machines, a shared network and rotating students, the layer matters as a standard rather than a choice: pick one implementation, write it down, and make every machine match, because half your lost afternoons will otherwise be somebody's laptop running a different one. If you are a startup heading for a product, the choice becomes a commitment, since the transport under your robot is something you will be asked about by customers, auditors and possibly a safety assessor. And if you are the person who inherited a robot that already works, the correct move is to change nothing until you can reproduce the failure, because an inherited system's configuration usually encodes a fix nobody documented.
What hardware are you running, and does that change which RMW you want?
Hardware changes the question more than it changes the answer. On a single small board with a handful of nodes, the delivery layer is rarely the constraint; the board's memory and the fact that every node carries its own copy of the transport matter more. On a board where a camera feeds a model and the model feeds a controller, the interesting problem is not which network protocol wins but how many times a large image gets copied between programs, which is a different subject — what shared memory means and why roboticists keep mentioning it is the plain version. Across two machines joined by a cable, most implementations behave themselves and the choice barely registers. Across wireless it matters a great deal, and the wireless network itself matters more than the choice. On microcontrollers the question changes shape entirely, since the small board usually speaks to the robot through a bridge process rather than running the transport itself.
How much time do you have before the robot has to work?
Your timeline decides whether this is a question you are allowed to ask. If a demonstration is two weeks out, do not touch the RMW layer; the swap itself takes an afternoon, and the retesting takes the fortnight you do not have, because everything about discovery and message settings shifts underneath you at once. If you have a quarter before a pilot, this is the right moment to decide deliberately, standardise every machine, and build the habit of recording what is installed where — the cost of that decision is small now and enormous after the fleet exists. If you are on a multi-year programme with customers and audits, the transport is a supplier decision rather than a technical preference, and the right time to make it is before the first line of application code, alongside your operating system and your hardware. The pattern underneath all three is the same: changing the delivery layer is cheap to do and expensive to trust, so the calendar question is never how long the change takes, but how long the re-verification takes.
What skill level does swapping the RMW actually require?
Swapping takes an hour and diagnosing takes a career, which is exactly the trap. The mechanical act is genuinely simple: install a package, set one environment variable on every machine that runs a node, and restart everything. A confident beginner can do it before lunch. What that beginner cannot do is tell whether it helped, because the symptom that prompted the swap was intermittent, the new implementation has different defaults, and the robot now behaves differently for reasons nobody has isolated. The skills that actually matter here are not exotic but they are specific: reproducing a fault on demand, changing one thing at a time, reading which nodes can see which others, and understanding the settings that govern whether a message is resent or dropped. Teams that struggle are almost never blocked by the difficulty of the swap; they are blocked by having made four changes on Friday and being unable to say on Monday which one mattered. If your team has nobody who works that way, hire or borrow that habit before you go anywhere near the transport.
What do you give up by changing the RMW under ROS 2?
You give up the well-trodden path, and that costs more than the change itself. Every tutorial, every forum answer, every course and most bug reports assume the default implementation, so from the moment you move you are slightly off the map — a maintainer's first question becomes whether the problem reproduces on the default, and you will spend time proving it does before anyone engages with your actual issue. You also inherit a second configuration surface: vendor-specific files with their own syntax, their own defaults and their own documentation, which somebody on your team now has to own. You add a rule that every machine must match, which sounds trivial until a new starter installs from a different guide. If you have gone commercial you have added a licence, a renewal and a conversation with procurement, which is fine when it buys support you will actually call and wasteful when it does not. Whether DDS is the right choice for your robot weighs the wider version of this trade.
When is ROS 2 the better choice?
ROS 2 is the better choice whenever the value of your robot is in code you did not write. If your machine needs to build a map of a building and drive to a goal, ROS 2 hands you navigation that hundreds of teams have already debugged, and reproducing that is not a project, it is a career. If your sensors and arms have supported drivers, ROS 2 is where they live. If you need visualisation, recording, playback and a simulator that speaks your message types, ROS 2 has all four and the alternatives have fragments. If you are hiring, ROS 2 is what candidates have used. HORUS is not the answer to any of those: it does not bring you a navigation stack, a driver catalogue or a decade of community answers, and a team that adopts it hoping for those will be disappointed in the first fortnight. Choose ROS 2 when the ecosystem is the point, and only look elsewhere when your problem is narrow, local to one machine, and not the sort of thing borrowed packages solve.
Is the RMW layer just an abstraction nobody asked for?
No, and here is why. The layer was added because the people who most wanted ROS 2 in products could not accept a transport they did not choose. A car maker with an approved supplier, a defence contractor with a certification path and a factory integrator with an existing network standard all need the plumbing to be theirs, and without a swap point none of them could adopt ROS 2 at all. The proof that the design earned its keep arrived later: when the community wanted a transport built for lossy wireless links, that option could be added underneath without asking a single application to change one line, and teams could evaluate it by changing a setting. Try to imagine that outcome in a system with the transport welded in. The genuine cost is exactly the one that brought you here — an extra layer to learn about on the day something breaks, and error messages that name libraries you did not choose. That cost is real, and smaller than the alternative: a middleware that only fits the people who wrote it.
Will switching your RMW fix a robot that misses its timing?
Partly, but not the way you think. Transport genuinely can be the cause: a message that has to be serialised, copied, queued and retried before a subscriber sees it is doing measurable work, and if a large image crosses that path several times per cycle, changing how it travels changes what your robot feels like. But teams reach for the transport first because it is the part with a name and a switch, and it is rarely the biggest term. A control loop sharing a processor with a logger will hurt you more. So will a Python node pausing to tidy up its memory, a driver that blocks while waiting for a device, and an operating system never set up to favour the loop over everything else. What real-time actually means in robotics sorts those causes apart. The useful discipline is to find which stage of the journey the time disappears in before changing the stage that has a convenient switch.
How do you decide what to do about the RMW under your robot?
Decide by symptom, in a fixed order, and stop as soon as the symptom explains itself. First, reproduce the fault deliberately — if you cannot make it happen on demand, you cannot tell whether anything you change helps. Second, check whether the two ends ever agreed to talk at all, because a settings mismatch that silently prevents a connection is the single most common cause and it looks exactly like a transport failure. Third, work out where the data actually travels: within one program, between programs on one board, between machines by cable, or over the air, since three of those four have nothing to do with your choice of vendor. Fourth, ask whether anything about your organisation forces the answer, such as a supplier requirement or a customer's approved list. Only then, if the fault is genuinely about how messages cross a network, change the implementation — one machine at a time, one change at a time, with the old configuration written down where you can find it again on a bad afternoon.
Decide by situation rather than by curiosity:
- If you are learning ROS 2 on one computer -> the default implementation, because every answer you will find assumes it.
- If your nodes cannot see each other across two machines -> check the message settings before the vendor, because a silent mismatch costs nothing to rule out.
- If a shared wireless network collapses when your robots start -> a transport built for lossy links, because discovery traffic is what is drowning you.
- If your product faces audits or an approved supplier list -> a commercial implementation with a contract, because the requirement is contractual rather than technical.
- If your real problem is two programs on one board passing large images -> a shared-memory middleware, because no network choice fixes copying.
When two options stay close, weigh them on the five axes of the HORUS Fit Framework — ecosystem size, setup effort, team size fit, deployment target, and licence — and take the one that loses on the fewest. No scores and no numbers: five honest questions about your situation rather than about the software. And if the answer you keep landing on is one machine, several programs and images that must not be copied between them, star HORUS on GitHub so it is in your list when you start building.