# ROS 2 topics, services and actions: when to use each

> Topics, services and actions solve different ROS 2 problems. Learn when to use each, how QoS settings drop messages and how to debug a stalled system.

Canonical: https://roboticsengineering.in/ros2-topics-services-actions/ | Published: 2026-10-27 | Updated: 2026-10-28 | Author: Jignesh Panchal

**Most ROS 2 bugs are not algorithm bugs. They are messages sent on the wrong channel.** Topics, services and actions look interchangeable when you are learning, then one of them blocks your control loop at the worst moment. Each exists because it solves a different timing and feedback problem.

This guide explains what each pattern is for, the QoS settings that silently drop messages, and how to debug a system where nodes are running but nothing arrives.

## Three patterns, three jobs

| Pattern | Shape | Use it for | Do not use it for |
| --- | --- | --- | --- |
| Topic | Publisher sends, any number of subscribers receive, no reply | Sensor streams, odometry, status, commands at a steady rate | Anything that needs a guaranteed answer |
| Service | Client calls, server replies once | Quick queries, mode changes, calibration triggers | Long tasks, anything that must be cancellable |
| Action | Client sends a goal, receives feedback, gets a final result | Navigation, docking, arm moves, anything taking seconds or minutes | High-rate data or simple state reads |

The test is simple: if the receiver must reply before the sender can continue, it is not a topic. If the task can take longer than a fraction of a second, it should not be a service.

## Topics: the default for streaming data

A topic is a named bus. Publishers write, subscribers read, and neither knows how many of the other exist. This decoupling is why ROS 2 systems scale: a LiDAR driver publishes `/scan` without caring whether one node or five consume it.

Commands are also topics when they are continuous. A velocity command published at 20 Hz is a topic, not a service, because the consumer wants the latest value and does not want to reply to every message.

```
ros2 topic list
ros2 topic info /scan --verbose
ros2 topic echo /scan --once
ros2 topic hz /odom
ros2 topic bw /camera/image_raw
```

`ros2 topic hz` and `ros2 topic bw` answer the two questions that matter first: is data arriving, and is it arriving at the rate and size you expect. A camera topic at 0.4 Hz is a driver problem, not a perception problem.

## Services: one question, one answer

A service is a remote function call with a typed request and typed response. It is the right choice for short, bounded operations: read a parameter set, trigger a calibration, clear an error, switch a mode.

The trap is using a service for work that takes time. The client blocks waiting for the response, the server may be busy, and there is no feedback and no cancellation. A service that takes eight seconds to return will make your operator interface feel broken even when it is working correctly.

```
ros2 service list -t
ros2 service type /robot/clear_faults
ros2 service call /robot/clear_faults std_srvs/srv/Trigger
```

Services are also stateful in a way that is easy to forget: if the server node restarts, pending calls fail. Code that treats a service call as reliable needs a timeout and a retry, not a bare call.

## Actions: long tasks with feedback

An action is built on topics and services but exposes the pattern every mobile robot needs: send a goal, receive progress, cancel if conditions change, and get a final result. Navigation, docking, arm trajectories and palletising all belong here.

| Action part | What it carries | Example |
| --- | --- | --- |
| Goal | What to achieve | Pose to reach, pallet pattern to build |
| Feedback | Progress while running | Distance remaining, current waypoint |
| Result | Final outcome | Success, failure code, final pose |
| Cancel | Stop request | Operator presses stop or a person enters the zone |

```
ros2 action list -t
ros2 action info /navigate_to_pose
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{pose: {header: {frame_id: map}, pose: {position: {x: 2.0, y: 1.0}}}}" --feedback
```

The `--feedback` flag is the difference between watching a robot work and guessing whether it is still working. Any operator interface you build should subscribe to feedback rather than polling a status topic.

## QoS: the setting that silently drops messages

ROS 2 adds Quality of Service profiles, and mismatched profiles are the most common reason a publisher and subscriber exist but never connect. The default for topics is reliable, which is fine for most data but wrong for high-rate sensor streams on a congested network.

| Setting | Options | Practical rule |
| --- | --- | --- |
| Reliability | Reliable / best effort | Reliable for commands and state, best effort for cameras and LiDAR |
| Durability | Volatile / transient local | Transient local for maps and static configuration |
| History | Keep last N / keep all | Keep last with a small depth unless replaying data |
| Depth | Queue size | 1 for commands, 5–10 for sensor data |

If `ros2 topic info --verbose` shows publishers and subscribers but `ros2 topic echo` shows nothing, check QoS before rewriting code. A best-effort subscriber will never receive from a reliable publisher in some middleware configurations, and a transient-local map will never reach a volatile subscriber.

## How the three fit in one robot

- **LiDAR and cameras** publish on topics at 10–30 Hz with best-effort QoS.
- **Odometry and joint states** publish on topics, reliable, small messages.
- **Velocity commands** publish on a topic at a fixed rate; the base stops if they stop arriving.
- **Navigation** is an action: goal, feedback, cancel, result.
- **Mode changes and fault clearing** are services, called from an operator interface with a timeout.

When a robot behaves strangely, check the channel type first. A missed service call looks like a frozen button; a dropped topic looks like a sensor failure; an action that never completes looks like a planner problem. Naming the pattern usually narrows the fault within minutes.

## Mistakes that cost debugging days

| Mistake | Symptom | Fix |
| --- | --- | --- |
| Service for a long task | UI freezes, calls time out | Convert to an action |
| Topic for a command that needs acknowledgement | Robot misses commands silently | Use a service or action |
| Reliable QoS on a camera | Latency grows, buffers fill | Best effort with depth 1–5 |
| No timeout on service calls | Node hangs when server restarts | Add a timeout and a retry policy |
| Custom message for a simple flag | Build and versioning overhead | Use `std_msgs` or `std_srvs` |
| One global namespace for two robots | Topics collide, commands cross | Namespaces per robot |

## A ten-minute debugging order

1. `ros2 node list` — are both ends running?
2. `ros2 topic info /topic --verbose` — do publisher and subscriber see each other, and do QoS profiles match?
3. `ros2 topic hz /topic` — is data arriving at the expected rate?
4. `ros2 topic echo /topic --once` — is the content sane?
5. `ros2 service list -t` or `ros2 action list -t` — does the interface exist under the name you expect?
6. `ros2 doctor` — any environment or middleware warnings?

Related: [ROS 2 for beginners](https://roboticsengineering.in/ros2-tutorial-beginners/), [ROS 2 launch files](https://roboticsengineering.in/ros2-launch-files-tutorial/), [Nav2 tutorial](https://roboticsengineering.in/ros2-nav2-tutorial/), [URDF tutorial](https://roboticsengineering.in/urdf-ros2-tutorial/), [ROS 2 vs ROS 1](https://roboticsengineering.in/ros2-vs-ros1/).

**What is the difference between a topic and a service in ROS 2?**

A topic is a one-way stream that any number of subscribers can read without replying. A service is a request that waits for a single response. Use topics for continuous data and services for short, bounded queries.

**When should I use an action instead of a service?**

When the task takes more than a fraction of a second, needs progress feedback, or must be cancellable. Navigation, docking and arm moves are actions; clearing a fault is a service.

**Why does ros2 topic echo show nothing when nodes are running?**

Usually a QoS mismatch, a namespace or topic name difference, or the publisher not actually publishing. Check ros2 topic info –verbose, then compare reliability and durability settings.

**What QoS should a camera use in ROS 2?**

Best effort with a small queue, usually depth 1 to 5. Reliable delivery on a high-rate image stream causes latency to grow when the network or subscriber falls behind.

**Do actions use topics and services internally?**

Yes. An action is built from a goal service, a result service and feedback topics, wrapped in a client-server pattern you normally interact with through the action API.

When the publisher lives on a microcontroller instead of a Linux host, [micro-ROS](https://roboticsengineering.in/micro-ros-tutorial/) is the way to join the same graph.

To inspect real topic traffic rather than guess, record it with [ros2 bag](https://roboticsengineering.in/ros2-bag-files-rosbag2/) and replay it later.

If a topic connects but no messages arrive, the cause is usually QoS. The [QoS tutorial](https://roboticsengineering.in/ros2-qos-tutorial/) covers reliability and durability compatibility in detail.

Hardware plugins skip topics entirely, as the [hardware interface tutorial](https://roboticsengineering.in/ros2-hardware-interface-tutorial/) shows.

When the built-in types do not carry the fields you need, define your own with [ROS 2 custom messages and interfaces](https://roboticsengineering.in/ros2-custom-messages-interfaces/).

## Sources and further reading

- [ROS 2 beginner client library tutorials](https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries.html) — publishers, subscribers, services and actions.
- [ROS 2 QoS settings](https://docs.ros.org/en/jazzy/Concepts/About-Quality-of-Service-Settings.html) — reliability, durability and history explained.
- [ROS 2 design documents](https://design.ros2.org/) — why the communication model changed from ROS 1.
- [Nav2 documentation](https://docs.nav2.org/) — a production example of actions used for navigation.
