ROS 2 QoS Profiles: Fixing Silent Sensor Data Drops and Connection Failures
ROS 2 QoS profiles decide whether your sensor data reaches its subscriber. Learn the trade-offs between BestEffort and Reliable delivery, how to size buffers, and how to debug mismatched connections.
07 Nov 2025, 07:26 UTC

When your sensor stream silently disappears
You launch your camera driver, your perception node starts, but no images arrive. No error, no warning—just silence. In ROS 2, this often traces back to Quality of Service (QoS) profiles: the delivery rules that determine whether a publisher and subscriber can talk to each other at all. Unlike ROS 1, where TCP connections were negotiated for you, ROS 2 sits on top of DDS (Data Distribution Service), a middleware that expects you to declare your delivery requirements explicitly. If those declarations don't match, the connection is rejected or messages vanish without a trace.
The three dials that control delivery
Every ROS 2 topic carries a QoS profile made of three policies that map directly to DDS settings. Understanding them is the difference between a robust pipeline and a mysterious bug.
- Reliability chooses between
BestEffortandReliable. BestEffort behaves like UDP: the publisher sends data and hopes for the best, with no retransmission. Reliable behaves like TCP: lost packets are resent, adding latency and bandwidth overhead. - History decides whether the middleware keeps a sliding window (
KeepLast) or every message ever sent (KeepAll). - Depth sets the size of that window when using
KeepLast. A depth of 1 means "only the freshest sample matters."
These are not abstract defaults. They are engineering trade-offs. A 60 Hz LiDAR stream on a congested Wi-Fi link usually wants BestEffort with a small depth. A command to stop a motor wants Reliable with enough depth to survive a momentary network hiccup.
Worked example: catching a mismatch with demo_nodes
The fastest way to see QoS in action is with the built-in demo nodes. Open a terminal with your ROS 2 environment sourced (standard user permissions are sufficient) and run a talker:
ros2 run demo_nodes_cpp talker
In a second terminal, simulate a common mistake: subscribe to the same topic but demand a different reliability policy. Use the topic echo CLI with a best-effort override:
ros2 topic echo /chatter --qos-reliability best_effort
Exact CLI flag names may vary slightly by ROS 2 distribution, but the concepts are stable. The subscriber now demands a policy the default talker does not offer. To confirm the diagnosis, inspect the topic from a third terminal:
ros2 topic info /chatter
Look for the QoS profile match status. When policies are incompatible, ROS 2 reports a mismatch rather than silently bridging the gap. The fix is alignment: either relax the subscriber to BestEffort or strengthen the publisher to Reliable.
Buffers, bandwidth, and the hidden cost of "Reliable"
Reliable QoS feels safe, but it is not free. At high frequencies, retransmission can saturate a network link and increase end-to-end latency—exactly the opposite of what a control loop needs. If your sensor data is inherently lossy (a video feed where frame N+1 makes frame N obsolete), BestEffort is usually the better engineering choice.
History and Depth carry their own memory cost. KeepAll guarantees no message is dropped by the middleware, but on a fast topic it can balloon memory usage until the process is killed. KeepLast with a depth of 1 or 2 keeps memory bounded and ensures late-joining subscribers see the most recent state, not a stale backlog.
An actionable checklist
Before you debug your algorithm, debug your QoS. Run ros2 topic info <topic> on every critical topic and confirm the profiles match. Ask three questions:
- Does this data need retransmission, or is freshness more important than completeness?
- How many samples does a subscriber actually need in its buffer?
- What happens if the network drops a packet—does the system fail safely or degrade gracefully?
QoS is not a ROS 2 implementation detail. It is a design decision you make explicit, verify with the CLI, and document alongside your topic interfaces.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.