G
Motorsport analyticsactive

Project dossier

GridPulse

Formula 1 telemetry analytics and replay platform for lap, sector, and driver comparison.

What it solves

Overview

GridPulse ingests race telemetry, normalizes high-frequency time-series data, and renders interactive replay and analysis views for speed, throttle, brake, gear, tires, and lap comparisons. Interview focus: explain FastF1 ingestion, cache behavior, full-session telemetry versus lap fallback, merge_asof alignment, one-second resampling, interpolation, lap/compound mapping, time-base shifting, race-control and team-radio normalization, replay request caching, and why one shared race clock prevents UI drift.

Target audience

Formula 1 fans exploring driver performance.Motorsport data analysts comparing laps and stints.Developers explaining time-series visualization systems.

System design

Architecture

A FastAPI backend fetches or accepts F1 telemetry, processes it into aligned series, and serves it to a React plus D3 visualization layer. Replay mode synchronizes charts and session state over time. The source backend loads FastF1 race sessions, enables a cache directory, merges position and car telemetry, resamples to one-second intervals, interpolates continuous channels, forward-fills discrete channels, computes global time bases, and returns replay-ready payloads consumed by React hooks and replay math utilities.

Architecture diagram

Diagram loads when visible

Ingestion layer

Fetches race, driver, lap, tire, and telemetry data from FastF1 or OpenF1 style sources.

PythonFastF1OpenF1

Processing layer

Aligns time-series channels, segments laps and sectors, and computes replay-ready samples.

Pythonpandas

API layer

Serves sessions, lap comparisons, telemetry channels, and replay metadata.

FastAPI

Visualization layer

Renders SVG and canvas-style views for speed traces, throttle/brake overlays, and replay panels.

ReactD3.js

FastF1 session layer

Loads seasons, race schedules, sessions, laps, weather, race-control messages, car data, and position data through FastF1.

FastF1f1_cachepandas

Replay normalization layer

Merges car and position streams, maps lap metadata onto telemetry, resamples to one-second rows, and shifts timestamps onto a frontend timeline.

merge_asofresampleinterpolate

Client replay cache layer

The React hook deduplicates telemetry and team-radio fetches by cache key so retries and re-renders do not hammer the backend.

useRaceReplayDataaxiosD3

Implementation surface

Tech stack

FastAPIBackend

Telemetry API, replay metadata, and processed session endpoints.

PythonBackend

Data ingestion, normalization, lap segmentation, and metric computation.

ReactFrontend

Interactive telemetry workspace and replay screens.

D3.jsLibrary

Custom SVG visualizations for lap traces and driver comparisons.

DockerDevops

Reproducible local and deployment environment.

FastF1 / OpenF1Library

Source data adapters for race telemetry and session metadata.

pandas merge_asofLibrary

Aligns telemetry rows with nearest car/position samples and latest lap metadata.

FastF1 cacheLibrary

Stores downloaded race/session data locally or in /tmp for hosted environments.

AxiosLibrary

Frontend data fetching for telemetry replay and team radio endpoints.

Replay math utilitiesLibrary

Binary search, time-window slicing, lap completion, pit-stop visibility, sector visibility, and race-clock formatting.

Operational flow

How it works

Telemetry is ingested from a race data source, normalized into comparable time-series channels, exposed through an API, and replayed in the browser with synchronized visualizations.

1

Load session data

The backend fetches race session, driver, lap, tire, and telemetry records for a selected event.

2

Normalize channels

Speed, throttle, brake, gear, RPM, and timestamps are aligned so comparisons use a common timeline.

3

Segment laps

The processor splits telemetry by lap and sector so driver comparisons are meaningful.

4

Serve analysis views

FastAPI returns processed traces, deltas, tire windows, and replay metadata to the frontend.

5

Synchronize replay

The browser advances a replay clock and updates every chart from the same timestamp.

6

Merge car and position telemetry

The backend merges car channels such as speed, throttle, brake, RPM, and gear with position channels such as X and Y using nearest-time alignment.

This prevents separate traces from drifting when the replay needs both motion and car-state channels.

7

Resample and fill channels

Telemetry is resampled to one-second rows, continuous channels are interpolated, and categorical channels such as lap, tire compound, gear, and DRS are forward-filled.

This creates smoother playback while keeping discrete racing state stable between raw samples.

8

Normalize race-control and radio messages

Frontend parsing converts mixed time formats into seconds and sorts messages so they appear at the right replay moment.

9

Compute replay visibility

Replay utilities decide whether laps, sectors, pit stops, race-clock messages, and time windows should be visible at the current replay time.

Sequence diagram

Diagram loads when visible

Concept depth

Key concepts

Telemetry channels arrive as sequences with timestamps. Comparing drivers requires alignment so speed, throttle, and brake values refer to the same moment or distance.

In GridPulse: GridPulse normalizes high-frequency F1 telemetry before rendering lap comparisons and replay.

Confidence

Implementation evidence

Code highlights

Replay cursor lookup

The replay engine finds the closest telemetry sample for the active replay time.

Code highlight loads when visible

Binary search avoids scanning every sample on each animation frame.

A shared elapsed time keeps speed, throttle, brake, and map views synchronized.

Telemetry normalization

Raw records are converted into a consistent shape before charts consume them.

Code highlight loads when visible

A consistent elapsed_ms axis makes frontend replay independent of source timestamps.

The chart layer receives cleaned values instead of source-specific column names.

Telemetry merge and resample

The backend creates replay-ready rows by aligning sources, resampling, interpolating continuous values, and forward-filling discrete state.

Code highlight loads when visible

Continuous and categorical channels are filled differently.

The tolerance prevents joining samples that are too far apart in time.

Replay request cache

The frontend caches in-flight replay requests so duplicate effects share the same network work.

Code highlight loads when visible

Failed requests are removed so retry can fetch again.

The key includes API URL, year, race, and retry token.

Contracts

API design

Base URL: http://localhost:8000/api

GET/sessions

Lists available seasons, races, and sessions for telemetry analysis.

GET/sessions/{sessionId}/telemetry

Returns processed telemetry channels for selected drivers and laps.

GET/sessions/{sessionId}/replay

Returns replay metadata and synchronized samples for playback.

GET/sessions/{sessionId}/compare

Returns lap deltas and channel overlays for driver comparison.

GET/api/build_info

Returns container build metadata so deployed environments can prove they are running the latest backend image.

GET/api/seasons

Returns seasons from 2018 through the current year for replay selection.

GET/api/{year}/{race_name}/race/team_radio

Returns team-radio messages normalized for the replay timeline when source data is available.

GET/api/{year}/{race_name}/race/weather

Returns weather samples used to explain stint, tire, and pace changes during the replay.

State model

Database design

Processed telemetry cache

Data relationship diagram

Diagram loads when visible

sessions

Race weekend metadata such as season, round, race name, and session type.

session_idseasonroundnametype

laps

Lap-level timing, driver, sector, and tire information.

lap_idsession_iddriverlap_numberlap_time

telemetry_samples

Aligned channel samples used by charts and replay.

lap_idelapsed_msspeedthrottlebrakegearrpm

driver_session

Driver-level race metadata including team color, classified position, total time, and driver number.

session_iddriver_numberabbreviationteam_colorclassified_positiontotal_time

race_control_message

Official messages normalized to replay seconds for timeline display.

session_idtimecategorymessageflagscope

team_radio_message

Team-radio snippets normalized to replay time and linked to driver/session metadata.

session_iddrivertimemessagesource_url

weather_sample

Weather readings for air temperature, track temperature, humidity, pressure, wind, and rainfall.

session_idtimeair_temptrack_temphumidityrainfallwind_speed

Architecture decisions

Trade-offs

Charting library

D3.js over Chart.js or Recharts

F1 telemetry needs custom scales, synchronized cursors, overlays, and non-standard interactions that are easier with D3 primitives.

Backend processing

FastAPI with Python over Browser-only parsing

Python has stronger data tooling for telemetry normalization, and the browser should receive replay-ready payloads.

Deployment runtime

Docker over Host-machine setup

Telemetry libraries can be environment-sensitive, so containers reduce setup drift.

Telemetry granularity

One-second resampled replay rows over Sending every raw high-frequency sample

Raw telemetry can be large and uneven. One-second rows are smoother for browser replay and reduce payload size, while still showing strategy and performance trends.

Source alignment

merge_asof with tolerance over Exact timestamp joins

Car and position data do not always share exact timestamps. Nearest-time joins with a tolerance recover usable rows without creating arbitrary matches.

Client request behavior

In-flight request cache over Every hook run starts new network calls

Telemetry replay payloads are heavy. Reusing identical in-flight promises protects the backend and improves page stability.

Replay timeline

Shared race clock over Independent component timers

Charts, map, lap panels, messages, sectors, and pit stops must agree on one current time to avoid replay drift.

Lessons learned

Challenges and solutions

Problem

Telemetry sources can have uneven sampling and missing channels.

Solution: Normalize timestamps, keep channel availability explicit, and make charts tolerant of missing series.

Lesson: Data visualization correctness starts with clear assumptions about source quality.

Problem

Replay views can drift if each chart manages its own time state.

Solution: Use one replay clock and derive all chart cursors from that shared elapsed time.

Lesson: Synchronized visualization needs a single source of temporal truth.

Problem

FastF1 versions and sessions can expose different message-loading capabilities.

Solution: Attempt session.load with messages and fall back to telemetry/laps/weather when messages are unsupported.

Lesson: External data libraries need compatibility paths around version differences.

Problem

Synthetic rows at time zero can make lap one appear to last through formation/grid delay.

Solution: Avoid injecting fake time-zero rows and leave leading LapNumber empty until the real first LapStartTime.

Lesson: Visualization fixes can corrupt domain meaning if they ignore race timing.

Problem

Race replay can fetch large payloads repeatedly during React effect reruns.

Solution: Cache in-flight replay requests and clear failed entries so retries remain explicit.

Lesson: Frontend data loading strategy matters when payloads are expensive.

Runbook

Requirements and future work

Requirements

  • Python 3.x with FastAPI for the processing API.
  • React and D3.js for custom telemetry visualizations.
  • Docker for reproducible local setup.
  • FastF1 or OpenF1-style data source for race telemetry.
  • FastF1 cache directory must be writable; hosted environments can use /tmp/f1_cache.
  • ALLOWED_ORIGINS must match the frontend origin unless wildcard mode is intentionally used.
  • Telemetry replay expects sessions with laps and telemetry available from FastF1 or local extracted CSVs.
  • Large races need payload-conscious frontend rendering and request deduplication.

Future improvements

  • Add live session monitoring when source latency allows it.
  • Persist processed race caches for faster repeat analysis.
  • Add tire degradation modeling and pit strategy simulation.
  • Add persistent processed-session cache keyed by year, race, session, driver set, and processing version.
  • Add distance-based interpolation for driver comparison views where elapsed time hides corner-by-corner differences.
  • Add source-quality badges for missing channels, interpolated segments, and fallback telemetry paths.
  • Add lap-delta explanations that connect time loss to throttle, brake, gear, DRS, tire, and weather changes.

Active recall

Interview Q&A

TradeoffsMedium

Why use D3 instead of a standard chart library?

02:00
ConceptsMedium

What makes telemetry comparison difficult?

02:00
ArchitectureHard

How do you prevent replay drift across charts?

02:00
ConceptsHard

Why use merge_asof for telemetry alignment?

02:00
TradeoffsMedium

Why resample telemetry to one-second intervals?

02:00
ConceptsMedium

Why should categorical telemetry be forward-filled instead of interpolated?

02:00
ArchitectureMedium

How does GridPulse avoid replay drift?

02:00
ConceptsHard

What is the purpose of time-base shifting?

02:00
CodeMedium

Why cache in-flight replay requests on the client?

02:00
ConceptsHard

What can go wrong if you inject a synthetic row at time zero?

02:00
ArchitectureHard

What would you add for production-grade telemetry caching?

02:00