Skip to main content

Optimize MCAP files

Bring your own storage and on-premises index-in-place sites read message data directly from your original files. Use the following recommendations to reduce query latency.

Prepare MCAP files so that:

  • Chunks use zstd or lz4 compression
  • Chunks are 4 MB or less
  • High-bitrate topics live in separate files
  • Chunk indexes are present (rebuild with mcap recover if missing)
  • Metadata is present so Foxglove can group data properly

Optimizing files​

Write optimized files from the start​

If you control the MCAP writer, configure it for optimized read performance.

import foxglove
from foxglove.mcap import MCAPCompression, MCAPWriteOptions

options = MCAPWriteOptions(
compression=MCAPCompression.Zstd, # or MCAPCompression.Lz4
chunk_size=1024 * 1024, # 1 MB
)

with foxglove.open_mcap(
"drive-camera.mcap",
writer_options=options,
channel_filter=lambda channel: channel.topic.startswith("/camera/"),
), foxglove.open_mcap(
"drive-telemetry.mcap",
writer_options=options,
channel_filter=lambda channel: not channel.topic.startswith("/camera/"),
):
# Log messages while both writers are open.
...

Process existing files before upload​

If you can't configure the writer, rewrite existing files before upload:

Inspect the file and correct errors with:

mcap info <filename>
mcap du <filename>
mcap list chunks <filename>
mcap doctor <filename>
mcap recover <filename>

Check the uncompressed chunk size (mcap list chunks) and which topics dominate file size (mcap du). Keep uncompressed chunk sizes to 4 MB or less. Large chunks or mixed high-bitrate topics in one file hurt query latency.

Splitting large topics into separate files allows for more selective reading of data and faster queries. Use mcap filter to partition topics:

mcap filter drive.mcap -o drive-camera.mcap \
--include-topic-regex '^/camera/.*' \
--compression zstd \
--chunk-size 1048576 # 1 MB

mcap filter drive.mcap -o drive-telemetry.mcap \
--exclude-topic-regex '^/camera/.*' \
--compression zstd \
--chunk-size 1048576 # 1 MB

If a file remains too large, split it further by time. Use the start / end values from mcap info (RFC3339 or nanoseconds):

mcap filter drive-camera.mcap -o drive-camera-part1.mcap \
--start 2026-07-14T10:00:00Z \
--end 2026-07-14T11:00:00Z \
--compression zstd \
--chunk-size 1048576 # 1 MB

mcap filter drive-camera.mcap -o drive-camera-part2.mcap \
--start 2026-07-14T11:00:00Z \
--compression zstd \
--chunk-size 1048576 # 1 MB

Add metadata and upload​

Use sessions or devices to group split recordings in Foxglove. This example uses the original filename as the session key; use any key that is unique within the project.

Set object metadata in the same operation as the upload:

SESSION_KEY="drive.mcap"
DEVICE_NAME="robot-1"
PREFIX="s3://your-bucket/robot-1/drives"

for file in drive-camera.mcap drive-telemetry.mcap; do
aws s3 cp "$file" "${PREFIX}/$(basename "$file")" \
--metadata "{\"foxglove_device_name\":\"${DEVICE_NAME}\",\"foxglove_session_key\":\"${SESSION_KEY}\"}"
done

See adding metadata to imports for more info.