> ## Documentation Index
> Fetch the complete documentation index at: https://playbook.smedleygroup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Telemetry

> Compare up to five loaded laps across gear, speed, throttle, brake and a time-delta pane.

## Overview

The Telemetry widget (`TelemetryCompare`) plots loaded laps across five stacked panes so you can compare exactly how two or more laps differ, not just by how much. Reach for it whenever a gap on the timing tower needs explaining: where on the lap it opened up, and in which channel.

> [!NOTE]
>
> There is no DRS or steering channel anywhere in this platform: OpenF1's car data carries neither. The five panes are Gear, Speed, Throttle, Brake and a computed Time Delta, top to bottom.

***

## What It Shows

![Telemetry comparing two laps across the five panes on the distance axis (Madrid 2026)](https://mintcdn.com/smedley_group/zwm6wmhxgH8zyABx/images/watchparty/telemetry.png?fit=max\&auto=format\&n=zwm6wmhxgH8zyABx\&q=85\&s=4c4f3acc854b556916b90fe550bea46f)

Five stacked panes, sharing one x-axis (toggleable between elapsed lap time and distance into the lap):

| Pane | Reads |
| - | - |
| Gear | Integer gear, drawn stepped (holds its value between samples) |
| Speed | km/h |
| Throttle | 0-100% pedal position, stepped |
| Brake | 0-100 (or 0/100 on-off, depending on source), stepped |
| Time Delta | Each other loaded lap's time gap to the FIRST loaded lap (the reference), computed against the reference's own distance/time coverage; a point outside that coverage plots as a gap, never an extrapolated guess |

Each loaded lap gets a legend entry (swatch plus label) at the top: solid, dashed, or dotted line style, cycling for laps that resolve to the same team colour (team-mates, or two laps of the same driver) so they stay tellable apart. A readout table to the right of the chart shows every channel's value at the current cursor position, one column per loaded lap: the value on the plotted axis is read exactly, and the other axis is interpolated. The read-out always reads the unsmoothed samples.

**Interactions**:

* **Drag a row** from the [Laps](/software/internal/watchparty/widgets/laps-table) table onto the widget to load it (up to 5 laps at once); drag again onto [Track Dominance](/software/internal/watchparty/widgets/track-dominance) on the same tab, which shares this loaded-lap state.
* **Time / Distance** toggle, top right; switching axis resets the cursor and any in-progress zoom or alignment.
* **Left-click** anywhere in the chart sets a sticky cursor, read out in the table.
* **Right-drag** zooms the x-axis only, to the selected range. The drag carries on if the pointer leaves the plot or the chart, and the zoom lands at the last point inside the plot when you let go. A right-click without a meaningful drag opens a small menu with **Reset zoom**, which returns to the full domain; the click changes nothing until you choose it. This is the same menu the other charts show, but Telemetry zooms along x only.
* **Right-click a legend entry** opens an "Align" menu; once armed, a left-drag nudges that lap's whole trace along the current axis (a manual per-lap offset, kept independently for time and distance) to correct for e.g. a mistimed lap start. A confirmed non-zero offset shows a reset control.
* A degraded-at-source lap's legend entry carries an amber warning glyph; see States below.

***

## Data Behind It

Each loaded lap is fetched once, on demand, over `GET /v1/sessions/{session_key}/telemetry?driver_number=&start=&end=` - a bounded window from the lap's own `date_start` to `date_start + lap_time` (or the next lap's start as a fallback when `lap_time` is null). Results are cached per (driver, lap) for the session; a failed fetch is cached as "failed" so the layer reads as no-data rather than a stuck spinner, and removing then re-dropping the lap is the retry path. There is no WebSocket `telemetry` channel subscription: lap rows arrive on the existing `laps` channel, and the trace itself is always fetched on demand rather than streamed.

Distance-into-lap is derived entirely client-side, a left-Riemann integral of `speed` over the lap window, because `car_telemetry` stores no distance column at source. This is a deliberate, flagged deferral: when a stored distance column lands, this derivation is dropped in favour of it and nothing else about the widget changes.

**Sector-anchored alignment.** Two laps of the same circuit rarely integrate to exactly the same distance, so before they are drawn each lap's distance axis is pinned to the circuit's own canonical sector lines, using that lap's measured sector times as knot points and anchoring the end at the official lap time. Two traces therefore line up at the same corner rather than drifting apart down the lap. Each lap reports its own verdict:

| Verdict | Meaning |
| - | - |
| Aligned | Pinned to the track definition's sector lines |
| Scaled | No sector pins available, so the lap is scaled to the canonical lap length |
| Raw | No scaling ran at all |

A lap can be unaligned for an honest reason: the circuit has no track definition, the definition has no measured sector lines, the lap has no sector times, or the trace itself is unusable. **A pit lap is never aligned**, in or out, because its distance profile is not a lap of the circuit. Pit laps and degraded traces are also flagged in their own right, without changing where the alignment pins sit.

**Display smoothing.** The speed and throttle traces are lightly smoothed along distance for legibility, with a gaussian kernel at 15 metres for speed and 2 metres for throttle. Gear, brake, the delta pane and the read-out table are never smoothed. The smoothing is display only: a missing sample stays missing and lends nothing to its neighbours.

***

## States

| State | Behaviour |
| - | - |
| No laps loaded | "Drag a lap here from the Laps table" |
| Lap unloadable | The lap has no measurable time window at all (e.g. no `date_start`); shown as a note, never fetched |
| Loading | Trace fetch in flight; shown as "`{label}` - loading trace" |
| Empty | Fetch completed (or failed) with zero usable points; "No telemetry data for this lap" |
| Ready | Full five-pane trace drawn |
| 5-lap cap | Dropping a sixth lap shows "5 laps maximum - remove one first" instead of loading it |
| Degraded at source | See below |
| Live vs replay | Both sources fetch the identical REST endpoint for a completed lap; the widget never branches on envelope `source` |
| Session type gating | None; Telemetry is available for every session category |

> [!WARNING]
>
> A degraded lap shows an amber warning badge in its legend entry, and the FIRST such lap loaded in a session fires a once-per-selection modal. See [Telemetry Degradation](/software/internal/watchparty/concepts/telemetry-degradation) for the full detection rule, the exact thresholds, and why it is not an ingestion fault.

***

## FAQ

> **Why does the Time Delta pane show a gap partway through one lap?**
>
> A point plots only where it falls inside the reference lap's own distance or time coverage. A reference lap that ended early (or a comparison lap that ran further) leaves the pane genuinely blank there rather than extrapolating.

> **Why did a menu open instead of zooming in?**
>
> A right-drag that moves only a few pixels is read as a click, which opens the **Reset zoom** menu, not a deliberate zoom. Drag further to commit to a zoomed range.

> **Why do two laps line up at every corner now?**
>
> Each lap's distance axis is pinned to the circuit's own sector lines using that lap's sector times, so the same corner sits at the same distance on both traces. A lap that cannot be pinned says so rather than pretending.

> **Is the speed trace the raw data?**
>
> The plotted speed and throttle lines are lightly smoothed for legibility. The read-out table beside the chart always shows the unsmoothed sample, so any number you quote is the real one.

***

## Next Steps

> **[Telemetry Degradation](/software/internal/watchparty/concepts/telemetry-degradation)**
>
> The frozen-sample detection rule behind the warning badge and modal.

> **[Track Dominance](/software/internal/watchparty/widgets/track-dominance)**
>
> See exactly two of these loaded laps mapped back onto the circuit.

> **[Laps](/software/internal/watchparty/widgets/laps-table)**
>
> Drag a row from here to load a lap into this widget.

> **[Data Journey](/software/internal/watchparty/concepts/data-journey)**
>
> How live and replay sources reach this widget identically.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.