Skip to main content
zerologszerologs
Back to Learn Hub
Gen3 Hardware Behaviour

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.

Last updated: July 30, 2026

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

hours

Active riding (state = RUN). ~360 entries/h on each board.

hours

Plugged in and charging. Measured ~50 BMS entries/h (AC onboard; DC unmeasured).

days

Parked time/day = 24 − riding − charging.

Parked: 20.50 h/day · MBB hibernation rate: ~31 entries/h (measured median) · BMS sleep rate: ~23 entries/h.
MBBFULL2,300 slots

9,069 written → 6,769 oldest lost

Only the most recent 1.8 days survive

Parked / hib4,449
Riding3,780
Charging840
BMSFULL2,300 slots

7,781 written → 5,481 oldest lost

Only the most recent 2.1 days survive

Parked / hib3,301
Riding3,780
Charging700

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.

MBBMain 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.

BMSBattery 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

MBB100%2,300 slots

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.

ExportEntriesOldest entry in the fileWindow
27 May 20247,97425 Feb 202492 days
31 May 20248,01828 Feb 202493 days
2 Jun 20248,03130 Mar 202465 days
5 Jun 20248,01130 Mar 202466 days
30 Jun 20248,10918 May 202443 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.

24 / dayMBB hibernation cycles while parked — exactly one per hour, declared by the firmware as Hibernating for 3600 sec
31 / cycleentries written per wake-up (median of 411 measured cycles, 416 if every hibernation marker counts; ~1,680 bytes)
~2,300total slots in the MBB buffer (131,200 bytes ÷ ~57 B per record)
~3 daysto fill the MBB buffer with nothing but hibernation: 131,200 ÷ 1,680 = 78 cycles = 3.25 days
5+ daysof being parked = ride data already overwritten on the MBB. These two rows are the same fact at two points in time: the buffer is full of hibernation after ~3 days, and every hour after that overwrites something older still — so by day 5 nothing from before the last ~3 days is left to find.
~50 / hBMS entries while actively charging: 48-72 an hour across the charge windows in our Gen3 BMS logs, a flat 60-second cadence. Charging is about twice the parked rate, not the order of magnitude this page used to print — the old “~1,200 / h” was the buffer size divided by an assumed two-hour fill, never a measurement. Every charging hour we hold is AC onboard; we have no DC fast-charge log, so the DC rate is unmeasured — not faster, not the same, unknown.

Technical 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

After a ride, plug the bike into the Zero app and export logs the same evening or the next day. Roughly 3 days of unbroken parking is enough to fill the MBB buffer with hibernation, so anything older than that is at risk. On a Gen2 bike the window is wider — a median of 78 days in our corpus — but it is still a window: keep the habit, just not the panic.

Export both MBB and BMS

The two boards have separate ring buffers with different fill rates. Uploading both lets us reconstruct ride and charge sessions even when one is partially overwritten.

Export regularly

Make it a habit — once a week, or after any ride you want to analyse. Each export is a snapshot; we'll merge the history together for you over time.

Don't leave the bike parked for weeks

If you can, ride a short loop before exporting. Long storage periods produce logs that look "empty" because hibernation entries dominate the buffer.

FAQ

My log is "empty" — can you recover the missing rides?

No. Once the ring buffer overwrites an entry the data is gone from the bike itself, and nothing on the server can bring it back. The only fix is to export sooner next time — ideally within 1–2 days of the ride you care about.

How long until a parked Gen3 bike loses its ride data?

About three days of unbroken parking. A parked Gen3 MBB runs exactly one wake-up cycle per hour — the firmware closes each one with "Saving Stats, Hibernating for 3600 sec" — and writes a median of 31 entries and 1,680 bytes per cycle, measured over 411 complete cycles in the 8 full-size native-Gen3 MBB app dumps we hold, framed by declared length. (A cycle here is a pair of consecutive 3,600-second markers 3,000 to 4,200 seconds apart; admit every hibernation marker instead and the same files give 416 cycles with identical medians.) The 131,200-byte buffer therefore holds about 78 cycles — 3.25 days — of pure hibernation, after which the oldest rides have already been overwritten. Do not assume the BMS file reaches further back: across the six same-bike, same-export MBB and BMS pairs measured here the BMS span runs from 0.19 times the MBB span to 20.9 times it, median 1.02 times. Download both.

Should I upload only the MBB or only the BMS file?

Always both. They record different things: the MBB carries bike state, motor, inverter and ambient temperatures, power limits, ride detection, fault events and — sparsely — motor rpm, road speed, shaft torque and an odometer; the BMS carries cell voltages, pack current, SOC and charge tracking, sampled far more often. We cross-reference the two to build the unified ride and charge sessions you see in the dashboard. The main board writes its speed and odometer only in its longest record type, roughly every four minutes while you ride, and the odometer only on newer firmware, so a ride reconstructed from the MBB alone can have timing, state and temperatures but a coarse distance or none. This answer described the MBB differently until September 2026; the correction is on the page above.

Does the same thing happen on a Gen2 bike?

Yes. Gen2 is a ring buffer too and it also overwrites. This page said the opposite until 2026-07-30 and was wrong to. The upstream format notes we rely on for Gen2 say it 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 MBB dump is a fixed 262,144 bytes; it does not grow. The size difference is about 2x, not 10x — 262,144 bytes against the Gen3 MBB's 131,200 — and 9 of the 135 Gen2 MBB dumps in our corpus are 131,072 bytes, smaller than a Gen3 dump. What genuinely differs is the parked write rate: a Gen2 bike barely writes while it sits, so the same 262 KB stretches much further. Our 128-day dump from a 2016 FXS contains exactly two "Entering Hibernate" lines, where a Gen3 MBB writes about 31 entries every hour. Across the 117 full-size Gen2 MBB dumps we hold, each file carries 2,800 to 9,229 entries covering a median of 78 days, half of them between 47 and 142 days. That is weeks to months, and it closes fast on a bike that is actually ridden: five consecutive exports from that same FXS each hold about 8,000 entries while the oldest entry left in the file marches forward from 25 February to 18 May 2024, and the 30 June export spans just 43 days. Export on the same cadence you would for a Gen3 — Gen2 buys you weeks, not immunity. See Gen2 vs Gen3 log differences.

How many entries does a Gen3 BMS ring buffer hold?

About 2,300 — but not because the records are a fixed size, and the exact count depends on how you frame the file. Splitting at the delimiter gaps, which is what our BMS decoder does, 7 native Gen3 BMS files (131,328 bytes each) give 15,998 data records from 16,005 0xB2 frames, one per file being the 0xFB header: 82.4 percent are variable-length 0xFD text events averaging 55 bytes, 11.3 percent are 52-byte 0x4B telemetry records, 4.3 percent are 78-byte 0x4D extended telemetry records and 0.5 percent are 70-byte 0x4C cell-detail records — a mean record of 57.5 bytes and 2,050 to 2,339 records per file. Chain the declared length instead, the convention the format itself uses, and the same seven files give 15,890 records, 2,038 to 2,327 per file, mixed 82.9 / 11.4 / 4.4 / 0.5 percent. Those are two conventions over one set of bytes, not two disagreeing measurements.

How fast does charging fill the BMS buffer?

Slower than this page used to claim. Measured over the charge sessions in our Gen3 BMS logs, a charging BMS writes 48 to 72 entries an hour, median about 50 — a steady 60-second cadence. Against a parked median of 23 an hour that is roughly double, not the order of magnitude this page previously published: the old "~1,200 entries an hour" was never measured, it was the ~2,300-slot buffer divided by an assumed two-hour fill time, which is the conclusion reasoned backwards into its own premise. At the measured rate, charging alone would take well over a day to wrap the buffer. Two things stay honestly open. Byte 37 of the payload reads mode 7 on 89% of charging samples but also on 84% of riding samples, so it is an awake/asleep flag rather than a charging flag. And every charging hour we hold is AC onboard — there is no DC fast-charge log in the set at all, so whether DC writes faster is not an order-of-magnitude estimate but a genuinely open question.

My data looks corrupt. Should I delete and re-upload?

If the symptom is "no rides" on a Gen3 log, deleting and re-uploading the same file will not change anything — the overwriting happened on the bike, not during upload. If you suspect a parsing error instead, use the Re-parse option in the report's Export menu; it re-runs the parser without re-uploading the file.

Which Zero models are Gen3?

Three different things get called a generation and they do not line up, so the answer depends on which one you mean. By product generation, from the owner manuals: the SR/F and SR/S (2020 onwards), the DSR/X (2023 onwards), the S, SR, DS and DSR from 2024, and the 2026 light line — LS1, XE and XB — are all generation 3 on Cypher III. The FX and FXS are generation 1 on the XMX platform, and the FXE (2022–2025) is generation 2 on XMX / Cypher II despite sharing the FX body. By log format, the native Gen3 ring buffer described on this page is what we have actually measured on SR/F, SR/S and DSR/X dumps; we hold no log from a 2024-or-later S, SR, DS or DSR, and none from the 2026 light line, so we cannot tell you what those files look like. By decoder routing, our parser treats {SR/F, SR/S, DSR/X, FXE} as Gen3 — so an FXE upload goes down the Gen3 path even though every FXE file we have is a 262,144-byte MBB\0 / BMS\0 dump handled by the 538XX decoder, a Gen2-lineage record format. All three statements are true at once, and a page that picks one without saying which sense it means is wrong. See the three senses of "generation", side by side.

Still confused or want to share feedback?