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.