ROS 2 bag files: record, inspect and replay properly

Record the right topics, compress sensibly, replay with simulated time and avoid the QoS and storage mistakes that make a rosbag useless.

Reference
RE-912
Published
Read
4 min

About the author · Sources, testing and AI policy

Robot test run being recorded on a laptop with terminal output

A rosbag is the black box recorder of a ROS 2 robot. When a navigation run fails at 2 a.m., the bag is the only way to see what the robot actually thought.

This guide covers recording the right topics, keeping bags small, replaying them with simulated time, and the file formats and gotchas that decide whether the bag is usable a week later.

Record the topics that matter, not everything

ros2 bag record -o nav_test_01 /scan /odom /tf /tf_static /cmd_vel

Recording everything with -a is convenient on a bench and expensive on a robot. Camera and point cloud topics can fill a disk in minutes. Add them only when the investigation needs them.

TopicRecordWhy
/scanYesLidar input for SLAM and Nav2
/odomYesWheel odometry and velocity
/tf, /tf_staticYesWithout transforms the bag is unreadable
/cmd_velYesWhat the controller actually commanded
/mapOptionalLarge, and usually reproducible
Camera imagesOnly when neededVery large at full rate
Point cloudsOnly when neededLargest topics on most robots

Storage format and compression

FormatNotes
sqlite3Long-standing default, easy to query
mcapFaster writes, better tooling, widely adopted in newer distributions
zstd compressionShrinks bags substantially, small CPU cost
ros2 bag record -o run_01 --compression-mode file \
  --compression-format zstd /scan /odom /tf /tf_static /cmd_vel

Compress when the bag leaves the robot. Leave compression off during live debugging, when you may want to read the file immediately.

Inspect before you trust a bag

ros2 bag info run_01

Check duration, message counts and topic list. A bag with zero /tf messages looks fine in the file listing and is useless for replay. Check it at the robot, not later.

Replay with simulated time

ros2 bag play run_01 --clock
# in another terminal
ros2 param set /use_sim_time true

Every node that consumes the bag must use simulated time. If one node reads wall time while the rest read bag time, TF lookups fail with extrapolation errors and you will chase a bug that does not exist on the robot.

  • Set use_sim_time on the launch file, not individually.
  • Start the replay, then start the consumers, or restart them after the clock is live.
  • Use --rate 0.5 when a heavy pipeline cannot keep up.
  • Use --start-offset to skip the boring first minute.
  • Do not run a live lidar at the same time as the bag on the same topic.

QoS mismatches

If a topic is recorded but stays empty, or replay produces no data for one topic, it is usually QoS. A sensor publisher using best-effort will not deliver to a subscriber asking for reliable. Record with a QoS override file when you need to force compatibility.

ros2 bag record -o run_02 --qos-profile-overrides-path qos.yaml /scan

A recording routine for field tests

  • Check free disk space before starting.
  • Use a bag name with date, robot ID and test purpose.
  • Record the core topics plus anything specific to the test.
  • Note the parameter file and map version used, in a text file beside the bag.
  • Run ros2 bag info immediately after stopping.
  • Copy the bag off the robot the same day.

The parameter file matters as much as the bag. A recording of a failure you cannot reproduce because the gains changed is a recording of a different robot.

Storage and retention

Bags are big. A lidar-only recording at 10 Hz is manageable; adding a camera turns hours into gigabytes. Keep a rotation policy: recent bags on the robot, everything else archived off-device, and a retention window measured in days, not months.

Mistakes to avoid

  • Recording without /tf, then discovering the bag cannot be visualised.
  • Mixing live and simulated time during replay.
  • Filling the robot’s disk mid-test.
  • Assuming a bag is valid because the command exited cleanly.
  • Recording a 4K camera stream to debug a wheel slip issue.
  • Losing the parameter file that made the run meaningful.

Related: ROS 2 topics, services and actions, TF2 tutorial, Nav2 tutorial, SLAM Toolbox tutorial, ROS 2 for beginners.

What is rosbag2 used for?

Recording and replaying ROS 2 topic data so you can debug a robot run later, share a failure with a colleague, or test a pipeline without the hardware.

Which topics should I record?

At minimum /scan, /odom, /tf, /tf_static and /cmd_vel. Add camera, map or point cloud topics only when the investigation needs them, because they fill storage quickly.

How do I replay a bag in ROS 2?

Run ros2 bag play with the –clock flag and set use_sim_time true on every consuming node, preferably in the launch file so nothing reads wall time mid-replay.

Why is my rosbag empty?

Common causes are a QoS mismatch between publisher and recorder, the topic not actually publishing, or the recorder started before the driver came up. Check with ros2 bag info and ros2 topic hz.

Is mcap better than sqlite3 for rosbags?

mcap writes faster and integrates well with modern tooling, while sqlite3 remains common and easy to query. Either works; check what your ROS 2 distribution supports best.

Record odometry and IMU together when you want to tune sensor fusion offline.

Recording a bag that contains custom types requires the same interface package to be installed, as covered in the custom messages guide.

Recording sessions is easier once your desktop toolchain is stable, and setting up ROS 2 on Windows is the usual starting point.

Sources and further reading

Pass it onWhatsAppLinkedIn

Keep reading

Continue learning

The Build Note

One short email when something is worth your bench time.

A new build sheet, a part price that moved, or a mistake worth avoiding. No daily drip, no recycled news.

One short email when a build or a price is worth your time. Unsubscribe in one click.