1<!doctype html> 2<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-spec/index" data-has-hydrated="false"> 3<head> 4<meta charset="UTF-8"> 5<meta name="generator" content="Docusaurus v3.10.2"> 6<title data-rh="true">MCAP Format Specification | MCAP</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:image" content="https://mcap.dev/img/og-image.jpeg"><meta data-rh="true" name="twitter:image" content="https://mcap.dev/img/og-image.jpeg"><meta data-rh="true" property="og:url" content="https://mcap.dev/spec"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="MCAP Format Specification | MCAP"><meta data-rh="true" name="description" content="[compression_formats]: ./registry.md#well-known-compression-formats"><meta data-rh="true" property="og:description" content="[compression_formats]: ./registry.md#well-known-compression-formats"><link data-rh="true" rel="icon" href="/img/favicon.png"><link data-rh="true" rel="canonical" href="https://mcap.dev/spec"><link data-rh="true" rel="alternate" href="https://mcap.dev/spec" hreflang="en"><link data-rh="true" rel="alternate" href="https://mcap.dev/spec" hreflang="x-default">
6<script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Specification","item":"https://mcap.dev/spec/"}]}</script>
6<script src="https://cdn.usefathom.com/script.js" data-site="RULHQVMR" data-spa="history" defer="defer"></script>
6<link rel="stylesheet" href="/assets/css/styles.453d6093.css">
7<script src="/assets/js/runtime~main.531854c9.js" defer="defer"></script>
vendor: 1 bytes, line 7
7
8<script src="/assets/js/main.425efa48.js" defer="defer"></script>
8 9</head> 10<body> 11<svg style="display: none;"><defs> 12<symbol id="theme-svg-external-link" viewBox="0 0 24 24"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol> 13</defs></svg>
14<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light")),document.documentElement.setAttribute("data-theme-choice",t||"system")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script>
14<div id="__docusaurus"><link rel="preload" as="image" href="/img/mcap64.webp"><div role="region" aria-label="Skip to main content"><a class="skipToContent_oPtH" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/mcap64.webp" alt="MCAP Logo" class="themedComponent_siVc themedComponent--light_hHel"><img src="/img/mcap64.webp" alt="MCAP Logo" class="themedComponent_siVc themedComponent--dark_yETr"></div><b class="navbar__title text--truncate">MCAP</b></a><a class="navbar__item navbar__link" href="/guides">Guides</a><a class="navbar__item navbar__link" href="/reference">API Reference</a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/spec">Specification</a><a class="navbar__item navbar__link" href="/inspect">Inspector</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><a href="https://foxglove.dev/chat" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Discord<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPrP"><use href="#theme-svg-external-link"></use></svg></a><a href="https://github.com/foxglove/mcap" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPrP"><use href="#theme-svg-external-link"></use></svg></a><div class="toggle_ki11 colorModeToggle_Hewu"><button class="clean-btn toggleButton_MMFG toggleButtonDisabled_Uw7m" type="button" disabled="" title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_k9hJ lightToggleIcon_lgto"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_k9hJ darkToggleIcon_U96C"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_k9hJ systemToggleIcon_E5c0"><path fill="currentColor" d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"></path></svg></button></div><div class="navbarSearchContainer_bzqh"></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_MB5r"><div class="docsWrapper__sE8"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_iEvu" type="button"></button><div class="docRoot_DfVB">
14<aside class="theme-doc-sidebar-container docSidebarContainer_c7NB"><div class="sidebarViewport_KYo0"><div class="sidebar_CUen"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_jmj1"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" href="/spec"><span class="linkLabel_fEdy">Specification</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/spec/registry"><span class="linkLabel_fEdy">Registry</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/spec/notes"><span class="linkLabel_fEdy">Implementation Notes</span></a></li></ul></nav></div></div></aside><main class="docMainContainer_a9sJ"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_Qr34"><div class="docItemContainer_tjFy"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_T5ub" aria-label="Breadcrumbs"><ul class="breadcrumbs"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_sfvy"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link">Specification</span></li></ul></nav><div class="tocCollapsible_wXna theme-doc-toc-mobile tocMobile_Ojys"><button type="button" class="clean-btn tocCollapsibleButton_iI2p">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>MCAP Format Specification</h1></header> 15<h2 class="anchor anchorTargetStickyNavbar_tleR" id="overview">Overview<a href="#overview" class="hash-link" aria-label="Direct link to Overview" title="Direct link to Overview" translate="no">â</a></h2> 16<p>MCAP is a modular container file format for recording timestamped <a href="https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern" target="_blank" rel="noopener noreferrer" class="">pub/sub</a> messages with arbitrary serialization formats.</p> 17<p>MCAP files are designed to work well under various workloads, resource constraints, and durability requirements.</p> 18<p>A <a href="http://kaitai.io" target="_blank" rel="noopener noreferrer" class="">Kaitai Struct</a> description for the MCAP format is provided at <a href="https://github.com/foxglove/mcap/blob/main/website/docs/spec/mcap.ksy" target="_blank" rel="noopener noreferrer" class="">mcap.ksy</a>.</p> 19<h2 class="anchor anchorTargetStickyNavbar_tleR" id="file-structure">File Structure<a href="#file-structure" class="hash-link" aria-label="Direct link to File Structure" title="Direct link to File Structure" translate="no">â</a></h2> 20<p>A valid MCAP file is structured as follows. The Summary and Summary Offset sections are optional.</p> 21<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><Magic><Header><Data section>[<Summary section>][<Summary Offset section>]<Footer><Magic></span><br></div></code></pre></div></div> 22<p>The Data, Summary, and Summary Offset sections are structured as sequences of <strong>records</strong>:</p> 23<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain">[<record type><record content length><record><record type><record content length><record>...]</span><br></div></code></pre></div></div> 24<p>Files not conforming to this structure are considered malformed.</p> 25<h3 class="anchor anchorTargetStickyNavbar_tleR" id="magic">
25Magic<a href="#magic" class="hash-link" aria-label="Direct link to Magic" title="Direct link to Magic" translate="no">â</a></h3> 26<p>An MCAP file must begin and end with the following <a href="https://en.wikipedia.org/wiki/File_format#Magic_number" target="_blank" rel="noopener noreferrer" class="">magic bytes</a>:</p> 27<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain">0x89, M, C, A, P, 0x30, \r, \n</span><br></div></code></pre></div></div> 28<p>The byte following "MCAP" is the major version byte. <code>0x30</code> is the ASCII character <code>0</code>. Any changes to this specification document (i.e. adding fields to records, introducing new records) will be binary backward-compatible within the major version.</p> 29<h3 class="anchor anchorTargetStickyNavbar_tleR" id="header">Header<a href="#header" class="hash-link" aria-label="Direct link to Header" title="Direct link to Header" translate="no">â</a></h3> 30<p>The first record after the leading magic bytes is the <a href="#header-op0x01" class="">Header</a> record.</p> 31<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><0x01><record content length><record></span><br></div></code></pre></div></div> 32<h3 class="anchor anchorTargetStickyNavbar_tleR" id="footer">Footer<a href="#footer" class="hash-link" aria-label="Direct link to Footer" title="Direct link to Footer" translate="no">â</a></h3> 33<p>The last record before the trailing magic bytes is the <a href="#footer-op0x02" class="">Footer</a> record.</p> 34<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><0x02><record content length><record></span><br></div></code></pre></div></div> 35<h3 class="anchor anchorTargetStickyNavbar_tleR" id="data-section">Data Section<a href="#data-section" class="hash-link" aria-label="Direct link to Data Section" title="Direct link to Data Section" translate="no">â</a></h3> 36<p>The data section contains records with message data, attachments, and supporting records.<
36/p> 37<p>The following records are allowed to appear in the data section:</p> 38<ul> 39<li class=""><a href="#schema-op0x03" class="">Schema</a></li> 40<li class=""><a href="#channel-op0x04" class="">Channel</a></li> 41<li class=""><a href="#message-op0x05" class="">Message</a></li> 42<li class=""><a href="#attachment-op0x09" class="">Attachment</a></li> 43<li class=""><a href="#chunk-op0x06" class="">Chunk</a></li> 44<li class=""><a href="#message-index-op0x07" class="">Message Index</a></li> 45<li class=""><a href="#metadata-op0x0c" class="">Metadata</a></li> 46<li class=""><a href="#data-end-op0x0f" class="">Data End</a></li> 47</ul> 48<p>The last record in the data section MUST be the <a href="#data-end-op0x0f" class="">Data End</a> record.</p> 49<h4 class="anchor anchorTargetStickyNavbar_tleR" id="use-of-chunk-records">Use of chunk records<a href="#use-of-chunk-records" class="hash-link" aria-label="Direct link to Use of chunk records" title="Direct link to Use of chunk records" translate="no">â</a></h4> 50<p>MCAP files can have Schema, Channel, and Message records written directly to the data section, or they can be written into Chunk records to facilitate indexing and compression. For MCAPs that include <a href="#chunk-index-op0x08" class="">Chunk Index</a> records in the summary section, all Message records should be written into Chunk records.</p> 51<blockquote> 52<p>Why? The presence of Chunk Index records in the summary section indicates to readers that the MCAP is indexed, and they can use those records to look up messages by log time or topic. However, Message records outside of chunks cannot be indexed, and may not be found by readers using the index.</p> 53</blockquote> 54<h3 class="anchor anchorTargetStickyNavbar_tleR" id="summary-section">Summary Section<a href="#summary-section" class="hash-link" aria-label="Direct link to Summary Section" title="Direct link to Summary Section" translate="no">â</a></h3> 55<p>The optional summary section contains records for fast lookup of file information or other data section records.</p> 56<p>The following records are allowed to appear in the summary section:</p> 57<ul> 58<li class=""><a href="#schema-op0x03" class="">Schema</a></li> 59<li class=""><a href="#channel-op0x04" class="">Channel</a></li> 60<li class=""><a href="#chunk-index-op0x08" class="">Chunk Index</a></li> 61<li class=""><a href="#attachment-index-op0x0a" class="">Attachment Index</a></li> 62<li class=""><a href="#metadata-index-op0x0d" class="">Metadata Index</a></li> 63<li class=""><a href="#statistics-op0x0b" class="">Statistics</a></li> 64</ul> 65<p>All records in the summary section MUST be grouped by opcode.</p> 66<blockquote> 67<p>Why? Grouping Summary records by record opcode enables more efficient indexing of the summary in the Summary Offset section.</p> 68</blockquote> 69<p>Channel records in the summary are duplicates of Channel records throughout the Data section.</p> 70<p>Schema records in the summary are duplicates of Schema records throughout the Data section.</p> 71<h3 class="anchor anchorTargetStickyNavbar_tleR" id="summary-offset-section">Summary Offset Section<a href="#summary-offset-section" class="hash-link" aria-label="Direct link to Summary Offset Section" title="Direct link to Summary Offset Section" translate="no">â</a></h3> 72<p>The optional summary offset section contains <a href="#summary-offset-op0x0e" class="">Summary Offset</a> records for fast lookup of summary section records.</p> 73<p>The summary offset section aids random access reading.</p> 74<h2 class="anchor anchorTargetStickyNavbar_tleR" id="records">Records<a href="#records" class="hash-link" aria-label="Direct link to Records" title="Direct link to Records" translate="no">â</a></h2> 75<p>MCAP files may contain a variety of records. Records are identified by a single-byte <strong>opcode</strong>. Record opcodes in the range 0x01-0x7F are reserved for future MCAP format usage. 0x80-0xFF are reserved for private records. 0x00 is not a valid opcode.</p> 76<p>Private records are application-specific and not defined within the MCAP spec.</p> 77<p>All MCAP records are serialized as follows:</p> 78<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><record type><record content length><record content></span><br></div></code></pre></div></div> 79<p>Record type is a single byte opcode, and record content length is a uint64 value.</p> 80<p>Records may be extended by adding new fields at the end of existing fields. Readers should ignore any unknown fields.</p> 81<blockquote> 82<p>The Message, DataEnd, and Footer records will not be extended, since their formats do not allow for backward-compatible size changes.</p> 83</blockquote> 84<p>Each record definition below contains a <code>Type</code> column. See the <a href="#serialization" class="">Serialization</a> section on how to serialize each type.</p> 85<h3 class="anchor anchorTargetStickyNavbar_tleR" id="header-op0x01">
85Header (op=0x01)<a href="#header-op0x01" class="hash-link" aria-label="Direct link to Header (op=0x01)" title="Direct link to Header (op=0x01)" translate="no">â</a></h3> 86<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>4 + N</td><td>profile</td><td>String</td><td>The profile is used for indicating requirements for fields throughout the file (encoding, user_data, etc). If the value matches one of the <a class="" href="/spec/registry#well-known-profiles">well-known profiles</a>, the file should conform to the profile. This field may also be supplied empty or containing a framework that is not one of those recognized.</td></tr><tr><td>4 + N</td><td>library</td><td>String</td><td>Free-form string for writer to specify its name, version, or other information for use in debugging</td></tr></tbody></table> 87<h3 class="anchor anchorTargetStickyNavbar_tleR" id="footer-op0x02">Footer (op=0x02)<a href="#footer-op0x02" class="hash-link" aria-label="Direct link to Footer (op=0x02)" title="Direct link to Footer (op=0x02)" translate="no">â</a></h3> 88<p>A Footer record contains end-of-file information. It must be the last record
88in the file. Readers using the index to read the file will begin with by reading the footer and trailing magic.</p> 89<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>8</td><td>summary_start</td><td>uint64</td><td>Byte offset of the start of file to the first record in the summary section. If there are no records in the summary section this should be 0.</td></tr><tr><td>8</td><td>summary_offset_start</td><td>uint64</td><td>Byte offset from the start of the first record in the summary offset section. If there are no Summary Offset records this value should be 0.</td></tr><tr><td>4</td><td>summary_crc</td><td>uint32</td><td>A CRC32 of all bytes from the start of the Summary section up through and including the end of the previous field (summary_offset_start) in the footer record. A value of 0 indicates the CRC32 is not available.</td></tr></tbody></table> 90<h3 class="anchor anchorTargetStickyNavbar_tleR" id="schema-op0x03">Schema (op=0x03)<a href="#schema-op0x03" class="hash-link" aria-label="Direct link to Schema (op=0x03)" title="Direct link to Schema (op=0x03)" translate="no">â</a></h3> 91<p>A Schema record defines an individual schema.</p> 92<p>Schema records are uniquely identified within a file by their schema ID. A Schema record must occur at least once in the file prior to any Channel referring to its ID. Any two schema records sharing a common ID must be identical.</p> 93<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>2</td><td>id</td><td>uint16</td><td>A unique identifier for this schema within the file. Must not be zero</td></tr><tr><td>4 + N</td><td>name</td><td>String</td><td>An identifier for the schema.</td></tr><tr><td>4 + N</td><td>encoding</td><td>String</td><td>Format for the schema. The <a class="" href="/spec/registry#well-known-schema-encodings">well-known schema encodings</a> are preferred. An empty string indicates no schema is available.</td></tr><tr><td>4 + N</td><td>data</td><td>uint32 length-prefixed Bytes</td><td>Must conform to the schema encoding. If <code>encoding</code> is an empty string, <code>data</code> should be 0 length.</td></tr></tbody></table> 94<p>Schema records may be duplicated in the summary section. A Schema record with an id of zero is invalid and should be ignored by readers.</p> 95<h3 class="anchor anchorTargetStickyNavbar_tleR" id="channel-op0x04">Channel (op=0x04)<a href="#channel-op0x04" class="hash-link" aria-label="Direct link to Channel (op=0x04)" title="Direct link to Channel (op=0x04)" translate="no">â</a></h3> 96<p>A Channel record defines an encoded stream of messages on a topic.</p> 97<p>Channel records are uniquely identified within a file by their channel ID. A Channel record must occur at least once in the file prior to any message referring to its channel ID. Any two channel records sharing a common ID must be identical.</p> 98<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>2</td><td>id</td><td>uint16</td><td>A unique identifier for this channel within the file.</td></tr><tr><td>2</td><td>schema_id</td><td>uint16</td><td>The schema for messages on this channel. A schema_id of 0 indicates there is no schema for this channel.</td></tr><tr><td>4 + N</td><td>topic</td><td>String</td><td>The channel topic.</td></tr><tr><td>4 + N</td><td>message_encoding</td><td>String</td><td>Encoding for messages on this channel. The <a class="" href="/spec/registry#well-known-message-encodings">well-known message encodings</a> are preferred.</td></tr><tr><td>4 + N</td><td>metadata</td><td><code>Map<string, string></code></td><td>Metadata about this channel</td></tr></tbody></table> 99<p>Channel records may be duplicated in the summary section.</p> 100<h3 class="anchor anchorTargetStickyNavbar_tleR" id="message-op0x05">Message (op=0x05)<a href="#message-op0x05" class="hash-link" aria-label="Direct link to Message (op=0x05)" title="Direct link to Message (op=0x05)" translate="no">â</a></h3> 101<p>A message record encodes a single timestamped message on a channel.</p> 102<p>The message encoding and schema must match that of the Channel record corresponding to the message's channel ID.</p> 103<table><thead><tr><th>
103Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>2</td><td>channel_id</td><td>uint16</td><td>Channel ID</td></tr><tr><td>4</td><td>sequence</td><td>uint32</td><td>Optional message counter to detect message gaps. If your middleware publisher provides a sequence number you can use that, or you can assign a sequence number in the recorder, or set to zero if this is not relevant for your workflow.</td></tr><tr><td>8</td><td>log_time</td><td>Timestamp</td><td>Time at which the message was recorded.</td></tr><tr><td>8</td><td>publish_time</td><td>Timestamp</td><td>Time at which the message was published. If not available, must be set to the log time.</td></tr><tr><td>N</td><td>data</td><td>Bytes</td><td>Message data, to be decoded according to the schema of the channel.</td></tr></tbody></table> 104<h3 class="anchor anchorTargetStickyNavbar_tleR" id="chunk-op0x06">Chunk (op=0x06)<a href="#chunk-op0x06" class="hash-link" aria-label="Direct link to Chunk (op=0x06)" title="Direct link to Chunk (op=0x06)" translate="no">â</a></h3> 105<p>A Chunk contains a batch of records. Readers should expect Schema, Channel, and Message records to be present in chunks, but future spec changes may include others. Private records may also be included. The batch of records contained in a chunk may be compressed or uncompressed.</p> 106<p>All messages in the chunk must reference channels recorded earlier in the file (in a previous chunk, earlier in the current chunk, or earlier in the data section).</p> 107<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>8</td><td>message_start_time</td><td>Timestamp</td><td>Earliest message log_time in the chunk. Zero if the chunk has no messages.</td></tr><tr><td>8</td><td>message_end_time</td><td>Timestamp</td><td>Latest message log_time in the chunk. Zero if the chunk has no messages.</td></tr><tr><td>8</td><td>uncompressed_size</td><td>uint64</td><td>Uncompressed size of the <code>records</code> field.</td></tr><tr><td>4</td><td>uncompressed_crc</td><td>uint32</td><td>CRC32 checksum of uncompressed <code>records</code> field. A value of zero indicates that CRC validation should not be performed.</td></tr><tr><td>4 + N</td><td>compression</td><td>String</td><td>compression algorithm. i.e. <code>zstd</code>, <code>lz4</code>, <code>""</code>. An empty string indicates no compression. Refer to <a class="" href="/spec/registry#well-known-compression-formats">well-known compression formats</a>.</td></tr><tr><td>8 + N</td><td>records</td><td>uint64 length-prefixed Bytes</td><td>Repeating sequences of <code><record type><record content length><record content></code>. Compressed with the algorithm in the <code>compression</code> field.</td></tr></tbody></table> 108<h3 class="anchor anchorTargetStickyNavbar_tleR" id="message-index-op0x07">Message Index (op=0x07)<a href="#message-index-op0x07" class="hash-link" aria-label="Direct link to Message Index (op=0x07)" title="Direct link to Message Index (op=0x07)" translate="no">â</a></h3> 109<p>A Message Index record allows readers to locate individual message records within a chunk by their timestamp.</p> 110<p>A sequence of Message Index records occurs immediately after each chunk. Exactly one Message Index record must exist in the sequence for every channel on which a message occurs inside the chunk.</p> 111<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>2</td><td>channel_id</td><td>uint16</td><td>Channel ID.</td></tr><tr><td>4 + N</td><td>records</td><td><code>Array<Tuple<Timestamp, uint64>></code></td><td>Array of log_time and offset for each record. Offset is relative to the start of the uncompressed chunk data.</td></tr></tbody></table> 112<p>Messages outside of chunks cannot be indexed.</p> 113<h3 class="anchor anchorTargetStickyNavbar_tleR" id="chunk-index-op0x08">Chunk Index (op=0x08)<a href="#chunk-index-op0x08" class="hash-link" aria-label="Direct link to Chunk Index (op=0x08)" title="Direct link to Chunk Index (op=0x08)" translate="no">â</a></h3> 114<p>A Chunk Index record contains the location of a Chunk record and its associated Message Index records.<
114/p> 115<p>A Chunk Index record exists for every Chunk in the file.</p> 116<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>8</td><td>message_start_time</td><td>Timestamp</td><td>Earliest message log_time in the chunk. Zero if the chunk has no messages.</td></tr><tr><td>8</td><td>message_end_time</td><td>Timestamp</td><td>Latest message log_time in the chunk. Zero if the chunk has no messages.</td></tr><tr><td>8</td><td>chunk_start_offset</td><td>uint64</td><td>Offset to the chunk record from the start of the file.</td></tr><tr><td>8</td><td>chunk_length</td><td>uint64</td><td>Byte length of the chunk record, including opcode and length prefix.</td></tr><tr><td>4 + N</td><td>message_index_offsets</td><td><code>Map<uint16, uint64></code></td><td>Mapping from channel ID to the offset of the message index record for that channel after the chunk, from the start of the file. An empty map indicates no message indexing is available.</td></tr><tr><td>8</td><td>message_index_length</td><td>uint64</td><td>Total length in bytes of the message index records after the chunk.</td></tr><tr><td>4 + N</td><td>compression</td><td>String</td><td>The compression used within the chunk. Refer to <a class="" href="/spec/registry#well-known-compression-formats">well-known compression formats</a>. This field should match the the value in the corresponding Chunk record.</td></tr><tr><td>8</td><td>compressed_size</td><td>uint64</td><td>The size of the chunk <code>records</code> field.</td></tr><tr><td>8</td><td>uncompressed_size</td><td>uint64</td><td>The uncompressed size of the chunk <code>records</code> field. This field should match the value in the corresponding Chunk record.</td></tr></tbody></table> 117<p>A Schema and Channel record MUST exist in the summary section for all messages in chunks that are indexed by Chunk Index records.</p> 118<blockquote> 119<p>Why? The typical use case for file readers using an index is fast random access to a specific message timestamp. Channel is a prerequisite for decoding Message record data. Without an easy-to-access copy of the Channel records, readers would need to search for Channel records from the start of the file, degrading random access read performance.</p> 120</blockquote> 121<h3 class="anchor anchorTargetStickyNavbar_tleR" id="attachment-op0x09">Attachment (op=0x09)<a href="#attachment-op0x09" class="hash-link" aria-label="Direct link to Attachment (op=0x09)" title="Direct link to Attachment (op=0x09)" translate="no">â</a></h3> 122<p>Attachment records contain auxiliary artifacts such as text, core dumps, calibration data, or other arbitrary data.</p> 123<p>Attachment records must not appear within a chunk.</p> 124<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>8</td><td>log_time</td><td>Timestamp</td><td>Time at which the attachment was recorded.</td></tr><tr><td>8</td><td>create_time</td><td>Timestamp</td><td>Time at which the attachment was created. If not available, must be set to zero.</td></tr><tr><td>4 + N</td><td>name</td><td>String</td><td>Name of the attachment, e.g "scene1.jpg".</td></tr><tr><td>4 + N</td><td>media_type</td><td>String</td><td><a href="https://en.wikipedia.org/wiki/Media_type" target="_blank" rel="noopener noreferrer" class="">Media type</a> (e.g "text/plain").</td></tr><tr><td>8 + N</td><td>data</td><td>uint64 length-prefixed Bytes</td><td>Attachment data.</td></tr><tr><td>4</td><td>crc</td><td>uint32</td><td>CRC32 checksum of preceding fields in the record. A value of zero indicates that CRC validation should not be performed.</td></tr></tbody></table> 125<h3 class="anchor anchorTargetStickyNavbar_tleR" id="metadata-op0x0c">Metadata (op=0x0C)<a href="#metadata-op0x0c" class="hash-link" aria-label="Direct link to Metadata (op=0x0C)" title="Direct link to Metadata (op=0x0C)" translate="no">â</a></h3> 126<p>A metadata record contains arbitrary user data in key-value pairs.</p> 127<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>4 + N</td><td>name</td><td>String</td><td>Example: <code>my_company_name_hardware_info</code>.</td></tr><tr><td>4 + N</td><td>metadata</td><td><code>Map<string, string></code></td><td>Example keys: <code>part_id</code>, <code>serial</code>, <code>board_revision</code></td></tr></tbody></table> 128<h3 class="anchor anchorTargetStickyNavbar_tleR" id="data-end-op0x0f">
128Data End (op=0x0F)<a href="#data-end-op0x0f" class="hash-link" aria-label="Direct link to Data End (op=0x0F)" title="Direct link to Data End (op=0x0F)" translate="no">â</a></h3> 129<p>A Data End record indicates the end of the data section.</p> 130<blockquote> 131<p>Why? When reading a file from start to end, there is ambiguity when the data section ends and the summary section starts because some records (i.e. Channel) can repeat for summary data. The Data End record provides a clear delineation the data section has ended.</p> 132</blockquote> 133<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>4</td><td>data_section_crc</td><td>uint32</td><td>CRC32 of all bytes from the beginning of the file up to the DataEnd record. A value of 0 indicates the CRC32 is not available.</td></tr></tbody></table> 134<h3 class="anchor anchorTargetStickyNavbar_tleR" id="attachment-index-op0x0a">Attachment Index (op=0x0A)<a href="#attachment-index-op0x0a" class="hash-link" aria-label="Direct link to Attachment Index (op=0x0A)" title="Direct link to Attachment Index (op=0x0A)" translate="no">â</a></h3> 135<p>An Attachment Index record contains the location of an attachment in the file. An Attachment Index record exists for every Attachment record in the file.</p> 136<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>8</td><td>offset</td><td>uint64</td><td>Byte offset from the start of the file to the attachment record.</td></tr><tr><td>8</td><td>length</td><td>uint64</td><td>Byte length of the attachment record, including opcode and length prefix.</td></tr><tr><td>8</td><td>log_time</td><td>Timestamp</td><td>Time at which the attachment was recorded.</td></tr><tr><td>8</td><td>create_time</td><td>Timestamp</td><td>Time at which the attachment was created. If not available, must be set to zero.</td></tr><tr><td>8</td><td>data_size</td><td>uint64</td><td>Size of the attachment data.</td></tr><tr><td>4 + N</td><td>name</td><td>String</td><td>Name of the attachment.</td></tr><tr><td>4 + N</td><td>media_type</td><td>String</td><td><a href="https://en.wikipedia.org/wiki/Media_type" target="_blank" rel="noopener noreferrer" class="">Media type</a> of the attachment (e.g "text/plain").</td></tr></tbody></table> 137<h3 class="anchor anchorTargetStickyNavbar_tleR" id="metadata-index-op0x0d">Metadata Index (op=0x0D)<a href="#metadata-index-op0x0d" class="hash-link" aria-label="Direct link to Metadata Index (op=0x0D)" title="Direct link to Metadata Index (op=0x0D)" translate="no">â</a></h3> 138<p>A metadata index record contains the location of a metadata record within the file.</p> 139<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>8</td><td>offset</td><td>uint64</td><td>Byte offset from the start of the file to the metadata record.</td></tr><tr><td>8</td><td>length</td><td>uint64</td><td>Total byte length of the record, including opcode and length prefix.</td></tr><tr><td>4 + N</td><td>name</td><td>String</td><td>Name of the metadata record.</td></tr></tbody></table> 140<h3 class="anchor anchorTargetStickyNavbar_tleR" id="statistics-op0x0b">Statistics (op=0x0B)<a href="#statistics-op0x0b" class="hash-link" aria-label="Direct link to Statistics (op=0x0B)" title="Direct link to Statistics (op=0x0B)" translate="no">â</a></h3> 141<p>A Statistics record contains summary information about the recorded data. The statistics record is optional, but the file should contain at most one.</p> 142<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>8</td><td>message_count</td><td>uint64</td><td>Number of Message records in the file.</td></tr><tr><td>2</td><td>schema_count</td><td>uint16</td><td>Number of unique schema IDs in the file, not including zero.</td></tr><tr><td>4</td><td>channel_count</td><td>uint32</td><td>Number of unique channel IDs in the file.</td></tr><tr><td>4</td><td>attachment_count</td><td>uint32</td><td>Number of Attachment records in the file.</td></tr><tr><td>4</td><td>metadata_count</td><td>uint32</td><td>Number of Metadata records in the file.</td></tr><tr><td>4</td><td>
142chunk_count</td><td>uint32</td><td>Number of Chunk records in the file.</td></tr><tr><td>8</td><td>message_start_time</td><td>Timestamp</td><td>Earliest message log_time in the file. Zero if the file has no messages.</td></tr><tr><td>8</td><td>message_end_time</td><td>Timestamp</td><td>Latest message log_time in the file. Zero if the file has no messages.</td></tr><tr><td>4 + N</td><td>channel_message_counts</td><td><code>Map<uint16, uint64></code></td><td>Mapping from channel ID to total message count for the channel. An empty map indicates this statistic is not available.</td></tr></tbody></table> 143<p>When using a Statistics record with a non-empty channel_message_counts, the Summary Data section MUST contain a copy of all Channel records. The Channel records MUST occur prior to the statistics record.</p> 144<blockquote> 145<p>Why? The typical use case for tools is to provide a listing of the types and quantities of messages stored in the file. Without an easy to access copy of the Channel records, tools would need to linearly scan the file for Channel records to display what types of messages exist in the file.</p> 146</blockquote> 147<h3 class="anchor anchorTargetStickyNavbar_tleR" id="summary-offset-op0x0e">Summary Offset (op=0x0E)<a href="#summary-offset-op0x0e" class="hash-link" aria-label="Direct link to Summary Offset (op=0x0E)" title="Direct link to Summary Offset (op=0x0E)" translate="no">â</a></h3> 148<p>A Summary Offset record contains the location of records within the summary section. Each Summary Offset record corresponds to a group of summary records with the same opcode.</p> 149<table><thead><tr><th>Bytes</th><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>1</td><td>group_opcode</td><td>uint8</td><td>The opcode of all records in the group.</td></tr><tr><td>8</td><td>group_start</td><td>uint64</td><td>Byte offset from the start of the file of the first record in the group.</td></tr><tr><td>8</td><td>group_length</td><td>uint64</td><td>Total byte length of all records in the group.</td></tr></tbody></table> 150<h2 class="anchor anchorTargetStickyNavbar_tleR" id="serialization">Serialization<a href="#serialization" class="hash-link" aria-label="Direct link to Serialization" title="Direct link to Serialization" translate="no">â</a></h2> 151<h3 class="anchor anchorTargetStickyNavbar_tleR" id="fixed-width-types">Fixed-width types<a href="#fixed-width-types" class="hash-link" aria-label="Direct link to Fixed-width types" title="Direct link to Fixed-width types" translate="no">â</a></h3> 152<p>Multi-byte integers (<code>uint16</code>, <code>uint32</code>, <code>uint64</code>) are serialized using <a href="https://en.wikipedia.org/wiki/Endianness" target="_blank" rel="noopener noreferrer" class="">little-endian byte order</a>.</p> 153<h3 class="anchor anchorTargetStickyNavbar_tleR" id="string">String<a href="#string" class="hash-link" aria-label="Direct link to String" title="Direct link to String" translate="no">â</a></h3> 154<p>Strings are serialized using a <code>uint32</code> byte length followed by the string data, which must be valid <a href="https://en.wikipedia.org/wiki/UTF-8" target="_blank" rel="noopener noreferrer" class="">UTF-8</a>.</p> 155<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><byte length><utf-8 bytes></span><br></div></code></pre></div></div> 156<h3 class="anchor anchorTargetStickyNavbar_tleR" id="bytes">Bytes<a href="#bytes" class="hash-link" aria-label="Direct link to Bytes" title="Direct link to Bytes" translate="no">â</a></h3> 157<p>Bytes is sequence of bytes with no additional requirements.</p> 158<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><bytes></span><br></div></code></pre></div></div> 159<h3 class="anchor anchorTargetStickyNavbar_tleR" id="tuplefirst_type-second_type">Tuple<first_type, second_type>
159<a href="#tuplefirst_type-second_type" class="hash-link" aria-label="Direct link to Tuple<first_type, second_type>" title="Direct link to Tuple<first_type, second_type>" translate="no">â</a></h3> 160<p>Tuple represents a pair of values. The first value has type first_type and the second has type second_type.</p> 161<p>Tuple is serialized by serializing the first value and then the second value:</p> 162<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><first value><second value></span><br></div></code></pre></div></div> 163<p>Example <code>Tuple<uint8, uint32></code>:</p> 164<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><uint8><uint32></span><br></div></code></pre></div></div> 165<p>Example <code>Tuple<uint16, string></code>:</p> 166<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><uint16><string></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"><uint16><uint32><utf-8 bytes></span><br></div></code></pre></div></div> 167<h3 class="anchor anchorTargetStickyNavbar_tleR" id="arrayarray_type">Array<array_type><a href="#arrayarray_type" class="hash-link" aria-label="Direct link to Array<array_type>" title="Direct link to Array<array_type>" translate="no">â</a></h3> 168<p>Arrays are serialized using a <code>uint32</code> byte length followed by the serialized array elements.</p> 169<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><byte length><serialized element><serialized element>...</span><br></div></code></pre></div></div> 170<p>An array of uint64 is specified as <code>Array<uint64></code> and serialized as:</p> 171<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><byte length><uint64><uint64><uint64>...</span><br></div></code></pre></div></div> 172<blockquote> 173<p>Since arrays use a <code>uint32</code> byte length prefix, the maximum size of the serialized array elements cannot exceed 4,294,967,295 bytes.</p> 174</blockquote> 175<h3 class="anchor anchorTargetStickyNavbar_tleR" id="timestamp">Timestamp<a href="#timestamp" class="hash-link" aria-label="Direct link to Timestamp" title="Direct link to Timestamp" translate="no">â</a></h3> 176<p><code>uint64</code> nanoseconds since a user-understood epoch (i.e unix epoch, robot boot time, etc.)</p> 177<h3 class="anchor anchorTargetStickyNavbar_tleR" id="mapkey_type-value_type">Map<key_type, value_type>
177<a href="#mapkey_type-value_type" class="hash-link" aria-label="Direct link to Map<key_type, value_type>" title="Direct link to Map<key_type, value_type>" translate="no">â</a></h3> 178<p>A Map is an <a href="https://en.wikipedia.org/wiki/Associative_array" target="_blank" rel="noopener noreferrer" class="">association</a> of unique keys to values.</p> 179<p>Maps are serialized using a <code>uint32</code> byte length followed by the serialized map key/value entries. The key and value entries are serialized according to their <code>key_type</code> and <code>value_type</code>.</p> 180<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><byte length><key><value><key><value>...</span><br></div></code></pre></div></div> 181<p>A <code>Map<string, string></code> would be serialized as:</p> 182<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain"><byte length><uint32 key length><utf-8 key bytes><uint32 value length><utf-8 value bytes>...</span><br></div></code></pre></div></div> 183<p>A serialization which has duplicate keys may cause indeterminate decoding.</p> 184<h2 class="anchor anchorTargetStickyNavbar_tleR" id="diagrams">Diagrams<a href="#diagrams" class="hash-link" aria-label="Direct link to Diagrams" title="Direct link to Diagrams" translate="no">â</a></h2> 185<p>The following diagrams demonstrate various valid MCAP files.</p> 186<h3 class="anchor anchorTargetStickyNavbar_tleR" id="empty-file">Empty file<a href="#empty-file" class="hash-link" aria-label="Direct link to Empty file" title="Direct link to Empty file" translate="no">â</a></h3> 187<p>The smallest valid MCAP file, containing no data.</p> 188<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain">[Header]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Footer]</span><br></div></code></pre></div></div> 189<h3 class="anchor anchorTargetStickyNavbar_tleR" id="single-message">Single Message<a href="#single-message" class="hash-link" aria-label="Direct link to Single Message" title="Direct link to Single Message" translate="no">â</a></h3> 190<p>An MCAP file containing 1 message.</p> 191<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain">[Header]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Schema A]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 1 (A)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on Channel 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Footer]</span><br></div></code></pre></div></div> 192<h3 class="anchor anchorTargetStickyNavbar_tleR" id="single-attachment">
192Single Attachment<a href="#single-attachment" class="hash-link" aria-label="Direct link to Single Attachment" title="Direct link to Single Attachment" translate="no">â</a></h3> 193<p>An MCAP file containing 1 attachment</p> 194<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain">[Header]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Attachment]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Footer]</span><br></div></code></pre></div></div> 195<h3 class="anchor anchorTargetStickyNavbar_tleR" id="multiple-messages">Multiple Messages<a href="#multiple-messages" class="hash-link" aria-label="Direct link to Multiple Messages" title="Direct link to Multiple Messages" translate="no">â</a></h3> 196<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain">[Header]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Schema A]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 1 (A)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 2 (A)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 2]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Schema B]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 3 (B)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Attachment]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 3]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Footer]</span><br></div></code></pre></div></div> 197<h3 class="anchor anchorTargetStickyNavbar_tleR" id="messages-in-chunks">Messages in Chunks<a href="#messages-in-chunks" class="hash-link" aria-label="Direct link to Messages in Chunks" title="Direct link to Messages in Chunks" translate="no">â</a></h3> 198<p>A writer may choose to put messages in Chunks to compress record data. This MCAP file does not use any index records.</p> 199<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain">[Header]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Chunk]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Schema A]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Channel 1 (A)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Channel 2 (A)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 2]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Attachment]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">
199[Chunk]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Schema B]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Channel 3 (B)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 3]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Footer]</span><br></div></code></pre></div></div> 200<h3 class="anchor anchorTargetStickyNavbar_tleR" id="multiple-messages-with-summary-data">Multiple Messages with Summary Data<a href="#multiple-messages-with-summary-data" class="hash-link" aria-label="Direct link to Multiple Messages with Summary Data" title="Direct link to Multiple Messages with Summary Data" translate="no">â</a></h3> 201<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain">[Header]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Schema A]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 1 (A)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 2 (A)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 2]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Schema B]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 3 (B)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Attachment]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 3]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Data End]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Statistics]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Schema A]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Schema B]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 2]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 3]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Summary Offset 0x01]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Footer]</span><br></div></code></pre></div></div> 202<h3 class="anchor anchorTargetStickyNavbar_tleR" id="multiple-messages-with-chunk-indices">Multiple Messages with Chunk Indices<a href="#multiple-messages-with-chunk-indices" class="hash-link" aria-label="Direct link to Multiple Messages with Chunk Indices" title="Direct link to Multiple Messages with Chunk Indices" translate="no">â</a></h3> 203<div class="language-text codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_t_Hd"><pre tabindex="0" class="prism-code language-text codeBlock_RMoD thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_AclH"><div class="token-line" style="color:#393A34"><span class="token plain">[Header]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Chunk A]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Schema A]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Channel 1 (A)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Channel 2 (B)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 2]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message Index 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message Index 2]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Attachment 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Chunk B]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Schema B]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Channel 3 (B)]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 3]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"> [Message on 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message Index 3]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Message Index 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Data End]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Schema A]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Schema B]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 2]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Channel 3]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Chunk Index A]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Chunk Index B]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Attachment Index 1]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Statistics]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Summary Offset 0x01]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Summary Offset 0x05]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Summary Offset 0x07]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Summary Offset 0x08]</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">[Footer]</span><br></div></code></pre></div></div> 204<h2 class="anchor anchorTargetStickyNavbar_tleR" id="further-reading">
204Further Reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further Reading" title="Direct link to Further Reading" translate="no">â</a></h2> 205<ul> 206<li class=""><a class="" href="/spec/notes#feature-explanations">Feature explanations</a>: includes usage details that may be useful to implementers of readers or writers.</li> 207</ul></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="row margin-top--sm theme-doc-footer-edit-meta-row"><div class="col noPrint_QeZL"><a href="https://github.com/foxglove/mcap/tree/main/website/docs/spec/index.md" target="_blank" rel="noopener noreferrer" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_bHB7" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_ydrU"></div></div></footer></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--next" href="/spec/registry"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Registry</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_XG6w thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#overview" class="table-of-contents__link toc-highlight">Overview</a></li><li><a href="#file-structure" class="table-of-contents__link toc-highlight">File Structure</a><ul><li><a href="#magic" class="table-of-contents__link toc-highlight">Magic</a></li><li><a href="#header" class="table-of-contents__link toc-highlight">Header</a></li><li><a href="#footer" class="table-of-contents__link toc-highlight">Footer</a></li><li><a href="#data-section" class="table-of-contents__link toc-highlight">Data Section</a></li><li><a href="#summary-section" class="table-of-contents__link toc-highlight">
207Summary Section</a></li><li><a href="#summary-offset-section" class="table-of-contents__link toc-highlight">Summary Offset Section</a></li></ul></li><li><a href="#records" class="table-of-contents__link toc-highlight">Records</a><ul><li><a href="#header-op0x01" class="table-of-contents__link toc-highlight">Header (op=0x01)</a></li><li><a href="#footer-op0x02" class="table-of-contents__link toc-highlight">Footer (op=0x02)</a></li><li><a href="#schema-op0x03" class="table-of-contents__link toc-highlight">Schema (op=0x03)</a></li><li><a href="#channel-op0x04" class="table-of-contents__link toc-highlight">Channel (op=0x04)</a></li><li><a href="#message-op0x05" class="table-of-contents__link toc-highlight">Message (op=0x05)</a></li><li><a href="#chunk-op0x06" class="table-of-contents__link toc-highlight">Chunk (op=0x06)</a></li><li><a href="#message-index-op0x07" class="table-of-contents__link toc-highlight">Message Index (op=0x07)</a></li><li><a href="#chunk-index-op0x08" class="table-of-contents__link toc-highlight">Chunk Index (op=0x08)</a></li><li><a href="#attachment-op0x09" class="table-of-contents__link toc-highlight">Attachment (op=0x09)</a></li><li><a href="#metadata-op0x0c" class="table-of-contents__link toc-highlight">Metadata (op=0x0C)</a></li><li><a href="#data-end-op0x0f" class="table-of-contents__link toc-highlight">Data End (op=0x0F)</a></li><li><a href="#attachment-index-op0x0a" class="table-of-contents__link toc-highlight">Attachment Index (op=0x0A)</a></li><li><a href="#metadata-index-op0x0d" class="table-of-contents__link toc-highlight">Metadata Index (op=0x0D)</a></li><li><a href="#statistics-op0x0b" class="table-of-contents__link toc-highlight">Statistics (op=0x0B)</a></li><li><a href="#summary-offset-op0x0e" class="table-of-contents__link toc-highlight">Summary Offset (op=0x0E)</a></li></ul></li><li><a href="#serialization" class="table-of-contents__link toc-highlight">Serialization</a><ul><li><a href="#fixed-width-types" class="table-of-contents__link toc-highlight">Fixed-width types</a></li><li><a href="#string" class="table-of-contents__link toc-highlight">String</a></li><li><a href="#bytes" class="table-of-contents__link toc-highlight">Bytes</a></li><li><a href="#tuplefirst_type-second_type" class="table-of-contents__link toc-highlight">Tuple<first_type, second_type></a></li><li><a href="#arrayarray_type" class="table-of-contents__link toc-highlight">Array<array_type></a></li><li><a href="#timestamp" class="table-of-contents__link toc-highlight">Timestamp</a></li><li><a href="#mapkey_type-value_type" class="table-of-contents__link toc-highlight">Map<key_type, value_type></a></li></ul></li><li><a href="#diagrams" class="table-of-contents__link toc-highlight">Diagrams</a><ul><li><a href="#empty-file" class="table-of-contents__link toc-highlight">Empty file</a></li><li><a href="#single-message" class="table-of-contents__link toc-highlight">Single Message</a></li><li><a href="#single-attachment" class="table-of-contents__link toc-highlight">Single Attachment</a></li><li><a href="#multiple-messages" class="table-of-contents__link toc-highlight">Multiple Messages</a></li><li><a href="#messages-in-chunks" class="table-of-contents__link toc-highlight">Messages in Chunks</a></li><li><a href="#multiple-messages-with-summary-data" class="table-of-contents__link toc-highlight">Multiple Messages with Summary Data</a></li><li><a href="#multiple-messages-with-chunk-indices" class="table-of-contents__link toc-highlight">Multiple Messages with Chunk Indices</a></li></ul></li><li><a href="#further-reading" class="table-of-contents__link toc-highlight">Further Reading</a></li></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Docs</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/guides">Guides</a></li><li class="footer__item"><a class="footer__link-item" href="/reference">API Reference</a></li><li class="footer__item"><a class="footer__link-item" href="/spec">Specification</a></li></ul></div>
207<div class="theme-layout-footer-column col footer__col"><div class="footer__title">Community</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://github.com/foxglove/mcap" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPrP"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://foxglove.dev/chat" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPrP"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://robotics.stackexchange.com/questions/tagged/mcap" target="_blank" rel="noopener noreferrer" class="footer__link-item">Robotics Stack Exchange<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPrP"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © <a href="https://foxglove.dev" style="color: inherit">Foxglove</a></div></div></div></footer></div> 208</body> 209</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.