Skip to main content

MCAP

logo

MCAP (pronounced "em-cap") is an open source container file format for logging and storing multimodal data. It supports multiple channels of timestamped pre-serialized data, and is ideal for use in pub/sub or robotics applications.

Pub/sub logging

Store multiple channels of timestamped log data, such as pub/sub messages or multimodal sensor data.

drawer-envelope

Serialization-agnostic

Record and replay binary messages in any format – like Protobuf, DDS (CDR), ROS, JSON, and more.

High-performance writing

MCAP uses a row-oriented, append-only design to minimize disk I/O and reduce the risk of data corruption during unclean shutdowns.

Self-contained

MCAP stores message schemas alongside data, so your files remain readable in the future even as your codebase evolves.

Efficient seeking

MCAP files contain an optional index, allowing for fast, efficient reading, even over a low-bandwidth internet connection.

Optional compression

Choose between LZ4 or Zstandard for chunk-based compression, while still supporting efficient indexed reads.

Broad language support

Native reader and writer libraries are available in C++, Go, Python, Rust, Swift, and TypeScript.

Flexible

Configure optional features like chunking, indexing, CRC checksums, and compression to make the right tradeoffs for your application.

Production-grade

MCAP is used in production by a wide range of companies, from autonomous vehicles to drones, and is the default log format in ROS 2.

Why not just use rosbag or SQLite?

MCAP was designed to solve the shortcomings of the recording formats that came before it — see the full design history for the underlying requirements.

rosbag1 (.bag)rosbag2 default (SQLite .db3)MCAP
Serialization agnosticNo — ROS1 serialization onlyYesYes — ROS 1/2, Protobuf, JSON, FlatBuffers, custom
Self-describing (schemas embedded)YesNot by default (ros2/rosbag2#782)Yes
Append-only / write-optimizedPartialNo — index updated per row insertYes — chunked, streaming-safe
Chunk-level compressionNoNo (message-level only)LZ4 or Zstandard
Corruption resiliencePartial (chunk-recoverable, no checksums)Depends on journal modeChunk CRCs + mcap recover
Efficient remote / random-access readsIndex-basedFull DB load required in browser (sql.js)Indexed reads over HTTP range, S3, GCS, Azure
Standards-track friendlyYesDifficult — SQLite has no independent second implementationYes — open spec, multiple implementations
Default in ROS 2Iron and earlierJazzy and later (current)

Write your first MCAP file

MCAP libraries are available in six languages. Pick one to see a minimal end-to-end example.

from mcap.writer import Writer

with open("out.mcap", "wb") as f:
writer = Writer(f)
writer.start()

schema_id = writer.register_schema(
name="ExampleMsg",
encoding="jsonschema",
data=b'{"type":"object","properties":{"value":{"type":"number"}}}',
)
channel_id = writer.register_channel(
schema_id=schema_id,
topic="/example",
message_encoding="json",
)

writer.add_message(
channel_id,
log_time=0,
data=b'{"value": 1.0}',
publish_time=0,
)

writer.finish()

Trusted by leading robotics teams