TL;DR: ROS/ROS 2 is the best tool to get started with robotics and do prototyping, but some of its strengths turn into challenges when you start developing for a safety critical product that must scale. Fortunately, other open source tools are more suitable for the job. This post is the kick-off on our learning journey, moving to a world beyond ROS .

The case for ROS

ROS 2 [1], the Robot Operating System 2 and successor of ROS, is the de facto standard for robotics platforms. Everyone dealing with robotics has heard of it, and most would be lost without it. The whole ecosystem has grown to a one-stop shop for students, educators, researchers and start-ups. It supplies almost everything you need to create the software for your own robot, from sensor drivers to visualization tools, state-of-the-art algorithms and all the glue that keeps it together. Researchers [2] often provide their new algorithms as ROS packages, ready for you to try out. Most even provide data sets recorded as rosbags, i.e. recorded ROS message data, to let others validate or play around with their work. Companies provide ROS drivers [3] to accelerate the adoption of their hardware within the robotics community. Combine all of this and you get an ecosystem whose value for prototyping is difficult to overstate.

When ROS Becomes a Problem

Unfortunately ROS 2's breadth comes at a cost, and it shows as soon as you move beyond prototyping and research. If you want to move towards professional product development, i.e. leaving the lab for testing and deploying robots in the real world, people will start to ask questions. Questions about safety, real time capability, software development processes and worst of all, which part of your software stack is ready to be certified for your target use case. You may be able to ignore this in the beginning, but you will have to answer at some point. It is either your investors, customers or worst case the legal advisors because things went really wrong. The following statements show some, but by far not all issues that can arise when using ROS 2 as the foundation for your product.

DDS as the default middleware

ROS 2 ships with DDS [4] (Data Distribution Service) as its default middleware. It is technically no longer mandatory as rmw_zenoh[5] and rmw_iceoryx [6] are available as non-DDS RMW alternatives, but DDS remains the default. The DDS API is hidden from the ROS 2 user, reducing parts of its complexity and capabilities. Research shows ROS 2 can introduce up to 50% latency overhead compared to using DDS communications directly, with end-to-end latency strongly dependent on the chosen DDS implementation [7]. Plenty of DDS related issues were reported over time which led to the conclusion that DDS might not be the best tool for robotics if the bulk of your work happens on one host. Read this post [8] and the attached report to learn more about the technical issues and the complexity, which led to Zenoh being supported as a Tier-1 ROS 2 middleware. While some DDS vendors offer shared memory as an option for intra-host communication, you still pay the overhead of DDS discovery, Quality-of-Service management and the like. DDS has its place in robotics, but it takes a conscious decision which middleware suits your application best.

A dedicated build system

If we ignore the ROS 2 middleware issues, there are plenty of other annoyances left. The colcon + ament_cmake stack simplifies many common project setups but adds a layer of abstraction that makes tailored setups difficult and sometimes impossible to achieve. Every ROS 2 package requires both a package.xml and a CMakeLists.txt, and the package.xml must declare all dependencies for colcon to resolve the build order [9]. While these abstractions help getting you started, they limit flexibility in adopting refined workflows and modern tools by locking you into an ecosystem that is hard to escape. In a perfect world, your middleware should not limit your higher level design decisions and tool setup.

A deep and opaque dependency footprint

Every C++ ROS 2 node, as minimalistic as it may be, links against rclcpp, which has a ton of transitive dependencies [10]. This shows the cost of convenience. ROS 2 handles lots of use cases and provides alternative middleware, all of this is abstracted away from the user and handled under the hood. Again, this was designed on purpose for its specific use case, but may not be appropriate for a slim and efficient production system.

No schema evolution

If a .msg file is changed, meaning a field is added, removed, renamed or reordered, every ROS 2 node in the system using this message must be recompiled against the new definition. There is no mechanism for forwards or backwards compatibility. A subscriber compiled against v1 of a message can't receive messages from a publisher compiled against v2.

While this may sound like a trivial problem, it is quite the opposite. As a system evolves, the interfaces usually evolve with it. If every single change in your ROS 2 messages is a breaking change, you have to be very good at versioning to keep your collected rosbags in line with your system. In the age of AI, data is money. Losing data is a critical issue. Every message change is a fork in your dataset history, and you have to handle the incompatibilities in your tools.

Imagine you collected data from the field for several months, spent hours on data curation and tens of thousands of dollars on the operation. Now you finally decide to fix a typo in your Odometry.msg and ... your ROS stack can't read the data anymore. In practice, interface changes are inevitable, but the underlying problem will remain. You will have to spend the effort to handle the changes, as minor as they may be. Fortunately, other IDLs like FlatBuffers handle this case more gracefully, where fields can be added or deprecated without breaking existing data.

The hardware reality

Most robotics products don't run on your trusty old desktop PC, but on embedded compute platforms, specifically ARM-based SoCs with constrained memory and limited compute. Cross-compilation from x86 machines is part of everyday life, and subtle architectural differences like memory ordering behavior can turn your code from "working in simulation" into a nightmare of silent bugs on the target platform.

On these systems, the dominant communication pattern is intra-host. Dozens of nodes exchange all the data they need, from small control messages at hundreds of Hz to large lidar pointclouds at a few frames per second. This is the environment where all of the problems listed above add up. The resource-devouring ecosystem, the endless transitive dependencies and the custom build tools that were not made for this application, they all pile up into a significant mess. You can spend your investor's money on solving this problem to create the necessary foundation of your product, or you could try to choose appropriate tools for the job and invest in what actually defines your product.

The list goes on

I don't want to go into more details here, the web is full of evidence what ROS 2 can and can't do, but if you are just starting on your product development journey you should spend some time on this decision. Review how successful robotics companies run their software and how much they rely on ROS 2. What you will find is that many established robotics scale-ups moved away from ROS 1 or 2 at this point. As I mentioned before, there is a good reason why people start with ROS 2, but there are plenty of reasons to move away from it as soon as you leave the experimentation phase.

How to move on

After reading about all those problems you probably want solutions. A link to a package or repo to download, maybe a 10-sentence guide how to replace ROS and finally make big bucks in robotics. Unfortunately there is no quick win like this, but the latest developments make it easier than ever to transition to a new middleware without losing all the nice utilities that ROS provided for introspection and other important tasks. The posts in our "Beyond ROS" series will take you along to learn how to use:

  • Zero-Copy IPC with Iceoryx2: A zero-copy middleware for intra-host communication. Replacing ROS/DDS for high performance and minimal latency communication.
  • FlatBuffers as a Universal Serialization Layer: A cross-platform serialization library for performance critical applications enabling forwards and backwards compatibility.
  • Building ROS-like Ergonomics: Replacing publish/subscribe patterns, services, actions and the parameter server with the new middleware.
  • Architectural Choices for Stable Products: How to leverage your new middleware's features for maximized performance.
  • Rethinking TF2: Bringing the transformation library to the new middleware.
  • Debugging and Observability: How to replace the beloved ros2 topic echo and RViz in our new system.
  • What you have to give up: Nothing is for free. Learn about the downsides of this transition to be able to make well informed decisions.

While we cover many theoretical concepts and learn about what makes a great middleware and which tools you really need, we will also keep it practical and provide working code examples in a playground repository, including a docker image with all required dependencies and some Rust sprinkled in for good measure.

Stay tuned for the next posts in this series, where we cover the basics of Iceoryx2 and Flatbuffers by writing and running some code. Join us for the journey beyond rapid prototyping and research in robotics, towards a production ready robotic system.

Resources

  1. Open Robotics — ROS 2 Documentation (Rolling), 2026 — https://docs.ros.org/en/rolling/index.html
  2. Vizzo, I., Guadagnino, T., Mersch, B., Wiesmann, L., Behley, J., Stachniss, C. — KISS-ICP: In Defense of Point-to-Point ICP — Simple, Accurate, and Robust Registration If Done the Right Way, IEEE Robotics and Automation Letters, 2023 — https://github.com/PRBonn/kiss-icp
  3. Ouster — ouster-ros: Official ROS driver for Ouster sensors, 2024 — https://github.com/ouster-lidar/ouster-ros
  4. Object Management Group — DDS (Data Distribution Service) Portal — https://www.omg.org/omg-dds-portal/
  5. Open Robotics — rmw_zenoh: ROS 2 RMW implementation using Zenoh — https://github.com/ros2/rmw_zenoh
  6. Open Robotics — rmw_iceoryx2: ROS 2 RMW implementation using iceoryx — https://github.com/ros2/rmw_iceoryx
  7. Kronauer, T., Pohlmann, J., Matthé, M., Smejkal, T., Fettweis, G. — Latency Overhead of ROS2 for Modular Time-Critical Systems, arXiv:2101.02074, 2021 — https://arxiv.org/abs/2101.02074
  8. Open Robotics — ROS 2 Alternative Middleware Report, ROS Discourse, 2023 — https://discourse.openrobotics.org/t/ros-2-alternative-middleware-report/33771
  9. Open Robotics — Creating Your First ROS 2 Package, ROS 2 Documentation (Rolling) — https://docs.ros.org/en/rolling/Tutorials/Beginner-Client-Libraries/Creating-Your-First-ROS2-Package.html
  10. Open Robotics — rclcpp/CMakeLists.txt (rolling branch) — https://github.com/ros2/rclcpp/blob/rolling/rclcpp/CMakeLists.txt