Why your Gen3 log shows no rides
The Gen3 boards on the SR/F, SR/S and DSR/X record diagnostic data into a small fixed-size ring buffer. If you wait too long before exporting, hibernation cycles silently overwrite your rides. Gen2 bikes wrap too — the window is just wider.
TL;DR
Each board (MBB and BMS) keeps its own ~128 KB ring buffer holding roughly 2,300 entries (measured 2,050–2,535 per file across 15 real Gen3 files — 8 MBB framed by declared length, 7 BMS framed at the delimiter gaps). A parked bike is not idle: the MBB wakes once an hour and writes a whole burst of entries — a measured median of 31 entries per wake-up cycle, not one — so a bike left alone fills its buffer with hibernation in about 3 days (3.25 at the measured median rate), and everything older than that is already gone. Export logs within 1–2 days of your last ride to keep useful telemetry.
See it for yourself — interactive simulator
Set how much you ride, charge and park per day, plus how many days have passed since the last log export. The two diagrams show what each board's ring buffer would look like when you finally pull the file.
Quick presets
Active riding (state = RUN). ~360 entries/h on each board.
Plugged in and charging. Measured ~50 BMS entries/h (AC onboard; DC unmeasured).
Parked time/day = 24 − riding − charging.
9,069 written → 6,769 oldest lost
Only the most recent 1.8 days survive
7,781 written → 5,481 oldest lost
Only the most recent 2.1 days survive
The buffer capacities and the two parked rates are measured from real logs: 15 native-Gen3 files (8 MBB, 7 BMS) and 411 complete hibernation cycles — pairs of consecutive Hibernating for 3600 sec markers 3,000 to 4,200 seconds apart — each spanning one parked clock-hour. Admit every hibernation marker, including the 18 that declare a year, and the same files give 416 cycles with identical medians; the backend quotes that variant. The riding and charging rates are order-of-magnitude estimates — our sample files are dominated by parked time, and actual rates vary with firmware version, ride pattern (lots of state changes vs steady cruise) and BMS reporting mode. One of those parked hours is published line by line if you want to see what a hibernation cycle actually writes. The intent is to make the trade-off visible, not to predict exact byte counts.
MBB vs BMS — two separate ring buffers
When you export logs from the Zero app you get two files per bike: one from the MBB and one from the BMS. They're independent computers, each with its own ring buffer, recording different things. Why this matters: a long charging session can fill the BMS buffer in hours while the MBB is still mostly empty — or vice-versa for long touring days.
MBB — Main Bike Board
Bike state, controller telemetry, power limits, ride detection, fault events.
- Buffer size
- ~131 KB
- Entry size
- ~57 B avg → 2,300 slots
- Filename
- VIN_MBB.bin or VIN_MbbD.bin
- Parked rate
- ~31 entries/h
- Riding rate
- ~360 entries/h
- Charging rate
- ~60 entries/h
Fills fastest when parked for a long time (hibernation cycles dominate) or during long rides.
BMS — Battery Management System
Cell voltages, pack current, SOC, BMS state machine, charge/discharge limits.
- Buffer size
- ~131 KB
- Entry size
- ~57 B avg → 2,300 slots
- Filename
- VIN_BMS0.bin / BMS1 / BmsD0
- Parked rate
- ~23 entries/h
- Riding rate
- ~360 entries/h
- Charging rate
- ~50 entries/h
Fills fastest during active charging — the BMS jumps into high-rate reporting mode (payload byte 37, record byte 45, = 7). A couple of hours of charging can fill the BMS buffer. The rate is measured on AC onboard charging, which is all our sample contains.
Always upload both. Our parser cross-references the two: MBB tells us when a ride started and what state the bike was in; BMS tells us how much energy moved and what the cells were doing. The MBB does carry a road speed and an odometer, but sparsely: both sit in the longer 0x52/0x53 records, which a running bike writes roughly every four minutes, and the odometer only on the newer of the two firmware layouts. The BMS samples far more often, which is why it stays the better source for anything electrical. This page described that differently until September 2026, on a measurement taken from the shortest record type — which ends before both fields — and generalised to the platform. One correction from July 2026 does stand: the 75-byte field once published here as an odometer is the 12 V accessory rail, a rail moving a tenth of a volt printed as tens of kilometres. With only one file, large parts of the ride/charge view will be empty — even if the other file on the bike was perfectly fine.
What is a ring buffer?
A ring buffer is a fixed-size storage area that wraps around on itself. When it's full, the next write replaces the oldest entry. There's no archive — what gets overwritten is gone forever.
Every Zero logging board works this way — the Gen3 MBB and BMS on the Cypher III / FST platform, and the Gen2 boards before them. On-board flash is small and writes are constant, so a genuinely append-only log would have filled the chip and stopped the board within months.
It is not a Cypher III invention. The older MBB\0 text-log format — what the S, SR, DS and DSR wrote through 2023, and what the whole FX / FXS / FXE family writes — is a ring buffer too. The upstream format notes we rely on for those files say so outright: the event log “appears to be a direct memory dump from a ring buffer”, and “bikes logs which exceed this offset begin overwriting themself from the top of the log data section”. A Gen2 dump is a fixed 262,144 bytes; it does not grow.
What Cypher III changed is the size of the window, and the difference is about 2×, not 10× — 262,144 bytes against the Gen3 MBB's 131,200, and 9 of the 135 Gen2 MBB dumps we hold are 131,072 bytes, i.e. smaller than a Gen3 dump. The real difference is the parked write rate: a Gen2 bike barely writes while it sits, so the same 262 KB stretches to a median of 78 days across the 117 full-size Gen2 MBB dumps here, against ~3 days for a parked Gen3.
Static example — buffer with mixed entries
Watching a Gen2 buffer wrap
Five consecutive exports from one 2016 FXS, five weeks apart end to end. The entry count barely moves — the buffer is full every time — while the oldest entry in the file marches forward by nearly three months. Those older entries were not archived anywhere; they were overwritten on the bike. Ride more and the window shrinks, which is why the last file covers 43 days where the first covered 92.
| Export | Entries | Oldest entry in the file | Window |
|---|---|---|---|
| 27 May 2024 | 7,974 | 25 Feb 2024 | 92 days |
| 31 May 2024 | 8,018 | 28 Feb 2024 | 93 days |
| 2 Jun 2024 | 8,031 | 30 Mar 2024 | 65 days |
| 5 Jun 2024 | 8,011 | 30 Mar 2024 | 66 days |
| 30 Jun 2024 | 8,109 | 18 May 2024 | 43 days |
538XX8Z19GCJ05XX8_MBB_*.bin, each 262,144 bytes, decoded with the upstream zero-log-parser. Across all 117 full-size Gen2 MBB dumps in this corpus a file holds 2,800–9,229 entries; trimming the oldest 5 % of timestamps per file to discount clock-reset strays, the window it covers has a median of 78 days, with half of the files between 47 and 142 days.
Why hibernation eats your MBB data
The MBB doesn't fully shut down when parked. Once an hour it wakes, runs a full start-up sequence, and goes back to sleep — and it is a burst, not a single line. A typical cycle logs the wake reason, the kill switch, the kickstand, the immobiliser, the RTC check, two state changes (STRT → PWSU → HIB), charge and discharge limits, four control-flag changes, two 12 V DC-DC entries and two binary state frames. The last line of every cycle names the interval itself: Saving Stats, Hibernating for 3600 sec. Across 411 complete cycles in the 8 full-size Gen3 MBB app dumps — framed by declared length, the way our MBB decoder frames them, and counting pairs of consecutive 3,600-second markers 3,000 to 4,200 seconds apart — the median cycle writes 31 entries and 1,680 bytes (p10 1,591, p90 1,744); 444 of 462 hibernation markers declared 3,600 seconds, the other 18 declaring 31,536,000 seconds (365 days — long-term storage mode). Count every marker rather than only the 3,600-second ones and the cycle total is 416, with the same medians. The BMS, by contrast, drops into a sleep mode that writes a median of 23 entries an hour when there's no current flow — but that does not make the MBB the binding constraint. Over the six same-bike, same-export MBB and BMS pairs here the BMS file's wall-clock span runs from 0.19× the MBB's to 20.9× it, median 1.02×. Download both.
Hibernating for 3600 secTechnical deep-dive
For developers and curious owners — here's how the on-bike storage is laid out and where the slot counts come from.
File size on the bike
Both dumps are 128 KiB aligned: 131,200 B for the MBB, 131,328 B for the BMS.
Neither board writes a fixed-size record, so the slot count is always file size ÷ mean record size. MBB entries average 55 B across the whole buffer (75-B binary state frames mixed with short ASCII events); the simulator above rounds that to ~57 B and ~2,300 slots, which sits inside the measured spread. Framing by declared length, the 8 full-size app dumps ran 2,238–2,535 records per file (median 2,383; 19,089 pooled). Counting raw 0xB2 delimiters with a plausible timestamp instead — a different, narrower population — gives 18,838, which is the figure this page published until 2026-07-30.
The BMS is not fixed 52 B. Across 15,998 data records in 7 native-Gen3 BMS files, framed at the 0xB2 gaps the way our BMS decoder frames them — 16,005 frames in all, one per file being the 0xFB header — the mix is 82.4% variable-length 0xFD text events (mean 55 B, range 28–192 B), 11.3% 52-byte 0x4B telemetry, 4.3% 78-byte 0x4D extended telemetry and 0.5% 70-byte 0x4C cell-detail records. Mean record: 57.5 B → ~2,300 slots (measured 2,050–2,339 per file). Chaining by the declared length instead of splitting at the gaps gives 15,890 records over the same seven files, 2,038–2,327 per file, and a mix of 82.9 / 11.4 / 4.4 / 0.5% — same bytes, different framing convention, so the two sets of numbers are not interchangeable. A 50-byte "FST Mono" telemetry variant on the SR/S 40-08201 board is handled by the parser but appears in none of these seven files.
Memory layout
Records start with a 0xB2 byte, then a declared length in byte 1, a type in byte 2 and a uint32 LE Unix timestamp in bytes 3–6. Entries are not in chronological order on disk, because the buffer wraps.
Splitting naively at every 0xB2 works on a native Gen3 BMS file — which is exactly what our BMS decoder does — and it is safe there: across the 15,998 gap-framed records the gap to the next delimiter matched the declared length in 95.7% of cases and was never shorter, so no record was ever cut in half.
It is not safe in general, though the reason is not the one this page gave until 2026-07-29. It said 0xB2 recurs inside payloads on the 538XX-firmware MBB variant. It does not: the writer escapes it, so 96,632 of 96,727 0xB2 bytes across the 14 538XX dumps our decoder adopts (99.90%) are genuine record starts, chaining by the declared length and resyncing at a tear. Of the 95 that are not, 61 fall interior to a chained record and 34 are never framed at all — and if you restrict "interior" to records whose declared length lands exactly on the next record start, only two are genuinely inside a payload; the other 59 sit at ring-wrap tears. The candidates the decoder rejects are something else again: unwritten ring-buffer slots — a slot the firmware has never reached still begins with 0xB2 and carries a zero timestamp, and there are 18,002 of those across the same 14 files (plus 3,104 whose timestamp is out of window). That decoder therefore accepts a candidate only when the uint32 at +3 of the unescaped record is a plausible timestamp (2019-01-01 to now + 365 days), and trusts the declared length in byte 1 rather than the gap. It does not chain from one record to the next, though — unlike the native Gen3 MBB decoder it advances one byte at a time and lets the timestamp gate and the per-type guards absorb the overlapping candidates that produces. Frame first, unescape second: unescaping the buffer before framing puts real 0xB2 bytes back into the middle of records, which is the failure that produced the wrong diagnosis in the first place.
Tooling (including this app) sorts by extracted Unix timestamp after parsing, then re-numbers entries.
MBB hibernation cycle
State sequence: STRT → PWSU → HIB, once an hour while parked. The sleep interval is not inferred — the firmware writes it: Hibernating for 3600 sec.
Each cycle produces a burst of entries — wake reason, switch states, immobiliser, RTC check, two state changes, power limits, control-flag changes, 12 V DC-DC — so a parked MBB accumulates a median of 31 entries and 1,680 bytes an hour even when nothing is happening. That is where a "no rides" log goes.
BMS reporting modes
The reporting mode lives at payload byte 37 of a 52-byte 0x4B telemetry record. The payload starts at record byte 8, so that is byte 45 of the record — not byte 37 of the entry.
The enum has seven values, not three. Counted over the 1,598 52-byte 0x4B rows the current decoder emits across the 7 Gen3 BMS files — the only class for which "payload byte 37" and "record byte 45" are the same byte: 1 = standard SOC reporting (32.7%), 3 = sleep (30.7%), 7 = active high-rate, during charge or discharge (27.3%), 4 (1.9%), 5 (1.8%) and 6 (1.8%). The remaining 3.8% read 0x00, 0xF0 or 0xFF — flash sentinels from partially overwritten records, not modes. The seventh value is 2, and it is written only by the 78-byte 0x4D record (520 of 619), whose payload sits 8 bytes later — so the mode byte is record byte 53 there, not 45. Those rows were invisible until the 2026-07 type dispatch started decoding them.
Population note: this page previously gave these shares over 1,557 rows. That was the population the decoder emitted before the July 2026 escape and type-dispatch fixes; it now emits 2,319, of which the 1,598 above are the 0x4B class. The distribution barely moved — but the label was wrong.
We publish no meaning for 4, 5 and 6. All three are rare, and all we can say from the data is what they are not: only 3 of the 88 rows carrying them have the byte-9 sleeping flag set (3.4%, against 88.4% on mode 3), so they are near-always waking states. Anything more specific would be a guess — and note that "never on a sleeping frame", which this page and the parser both used to assert, is not true on the current population.
Mode 7 is also not a charging flag, which matters for anyone trying to detect charging from it: it reads on 89% of charging samples but on 84% of riding samples too, so what it really separates is awake from asleep. A charging BMS writes a measured 48-72 entries/hour, median ~50 — this page previously said ~1,200, which was the buffer size divided by an assumed fill time rather than anything counted. All of those hours are AC onboard; we hold no DC fast-charge log, so the DC rate is an open question rather than an estimate.
For the full record-by-record spec — every 0xB2 record type, the state field offsets, telemetry encoding, the 538XX firmware variant and the timestamp extraction quirks — read the Gen3 binary log format reference.
How to recognise an overflowed log
When you upload a Gen3 log we run a quick check on the entries. You'll see one of these warnings on the report:
- Gen3 log: data limited to roughly the last 3 days before export.
Always shown on Gen3 logs as a reminder. Doesn't mean anything is wrong — it just sets expectations.
- No ride data found: the ring buffer contains only hibernation cycles.
The buffer was filled by wake/sleep cycles before you exported. Your rides happened, but they're no longer in this file. Re-exporting now won't help — the data is gone from the bike.
How to capture more data
Export within 1–2 days
Export both MBB and BMS
Export regularly
Don't leave the bike parked for weeks
FAQ
My log is "empty" — can you recover the missing rides?
How long until a parked Gen3 bike loses its ride data?
Should I upload only the MBB or only the BMS file?
Does the same thing happen on a Gen2 bike?
How many entries does a Gen3 BMS ring buffer hold?
How fast does charging fill the BMS buffer?
My data looks corrupt. Should I delete and re-upload?
Which Zero models are Gen3?
Keep reading
Specification
The Gen3 binary log format
Record-by-record spec: every 0xB2 record type, byte offsets, framing rules and the 538XX firmware variant.
Comparison
Which generation is my Zero?
How Gen2 text logs and Gen3 ring buffers differ, and which telemetry each generation actually records.
Foundations
How Zero logs work
What MBB and BMS logs contain and how they're parsed into structured data.
Practical
Reading your logs
A walk-through of the dashboard and what to look at first when something seems off.