Engineering Guides · Module 19
ROS bag recording strategy
Record what you will need to explain a failure, within the disk and the CPU you have, and keep the last minutes in memory.
Assumptions: Numbers in the examples are illustrative and the code is executed by the site’s tests. Facts taken from a cited source are marked; other statements are general engineering knowledge and must be confirmed on the datasheet of the part you use.
1. Engineering problem
Failures cannot be reproduced on demand, so the recording is the evidence. Recording everything can fill a disk in hours or overload the computer; recording too little leaves nothing to analyse.
2. When is this needed?
- Setting up logging for field tests and deployments.
- When a failure happened and there was no usable recording.
- When bags are too big.
3. Selection and design decisions
The rosbag2 README (jazzy, read 2026-11-06) documents: compression is off by default; the only compression format available is zstd, enabled with --compression-mode (for example file) and --compression-format zstd; bags can be split by size or duration (--max-bag-size, --max-bag-duration); storage plugins are mcap and sqlite3; QoS can be overridden with --qos-profile-overrides-path (necessary to record best-effort topics reliably); and snapshot mode (--snapshot-mode) keeps an in-memory circular buffer and writes it only when the ~/snapshot service is called, “capturing the last N bytes of incoming data” around an error or point of interest.
| Choice | Effect | Note |
|---|---|---|
| Topic list vs all | Controls rate and size | Always include /tf, /tf_static, camera_info and the diagnostics |
| Raw images and clouds | Dominate the data volume | Record compressed images or cropped clouds if the analysis allows |
| Compression (zstd) | Smaller files, more CPU | Ratio depends on the data |
| Splitting | Manageable files, safer on a crash | Choose by size or duration |
| Snapshot mode | Records only around events | Needs a trigger and memory for the buffer |
| Storage plugin | mcap or sqlite3 | Check tool support in your pipeline |
4. Advantages and disadvantages
- Record everything is simple and expensive; selected topics need foresight.
- Compression saves disk and costs CPU on a loaded computer.
- Snapshot mode saves disk and misses what happened before the buffer.
5. Requirements and constraints
- Disk budget for the longest mission with margin.
- Recording does not starve the robot’s own CPU or disk I/O.
- Clock and metadata (software version, configuration) are recorded with the bag.
6. Architecture
topics ─▶ rosbag2 recorder (QoS overrides, compression, splitting) ─▶ disk
└▶ snapshot buffer in memory ─▶ dumped on an event7. Implementation
- List the topics needed to analyse each failure type.
- Estimate the data rate and disk need (below).
- Choose compression, splitting and snapshot settings.
- Test recording under full robot load.
- Check a bag by replaying it (see the bag replay guide).
topics = {"/scan": (40e3, 10), "/points": (2.1e6, 10), "/camera/image_raw": (2.76e6, 15), "/imu/data": (300, 200), "/tf": (2e3, 50), "/odom": (700, 50)} # (bytes per message, Hz)
raw = sum(b * hz for b, hz in topics.values())
print(f"uncompressed rate: {raw / 1e6:.1f} MB/s = {raw * 3600 / 1e9:.0f} GB per hour")
excl = {k: v for k, v in topics.items() if k != "/camera/image_raw"}
print(f"without the raw camera: {sum(b * hz for b, hz in excl.values()) / 1e6:.1f} MB/s")
ratio = 0.5 # assumed compression ratio (illustrative; depends on the data)
print(f"with compression at an assumed ratio {ratio}: {raw * ratio * 3600 / 1e9:.0f} GB per hour")
disk_gb = 500
print(f"500 GB disk holds about {disk_gb / (raw * 3600 / 1e9):.1f} hours uncompressed")
snap_s = 30
print(f"snapshot buffer for the last {snap_s} s needs about {raw * snap_s / 1e6:.0f} MB of memory")Printed (checked by the site’s tests):
uncompressed rate: 63.0 MB/s = 227 GB per hour
without the raw camera: 21.6 MB/s
with compression at an assumed ratio 0.5: 113 GB per hour
500 GB disk holds about 2.2 hours uncompressed
snapshot buffer for the last 30 s needs about 1890 MB of memoryReading it: the example topic set is 63 MB/s (227 GB per hour), of which the raw camera is two thirds; without it 21.6 MB/s; with an assumed compression ratio of 0.5 about 113 GB per hour; a 500 GB disk holds 2.2 hours uncompressed; and a 30 s snapshot buffer needs about 1.9 GB of memory. Sizes and rates are illustrative.
8. Real examples
- Delivery robot: snapshot mode with a 30 s buffer, dumped when the localisation monitor raises an error; full recording only on test days.
9. Failure scenarios
- No /tf_static in the bag, so nothing transforms on replay.
- The disk fills overnight.
- A recorder that overloads the CPU and causes the failure it is meant to capture.
10. Troubleshooting
- Check message counts per topic against the expected rates.
- Check CPU and disk write speed while recording.
- Check that QoS overrides were used for best-effort topics.
11. Validation
- The calculation prints the lines shown (executed by the site tests).
- A test bag replays and contains every topic and the expected counts.
12. Engineering checklist
13. Further references
- rosbag2 README (jazzy): ros2/rosbag2, read 2026-11-06.