PitWall
Problem
Real-time Formula 1 telemetry and race strategy engine. A Go ingestion pipeline streams live timing and telemetry data through NATS JetStream into TimescaleDB hypertables with continuous aggregates. A strategy engine computes two-piece linear tire degradation curves, fuel-corrected lap time projections, and undercut/overcut recommendations against a roughly 22-second pit stop delta. Results stream to a React/TypeScript dashboard over WebSocket with D3.js tire-life timelines.
Constraints
- -Telemetry ingestion must keep up with live race timing feeds without falling behind
- -Tire degradation and pit-window math must update continuously as lap data streams in, not as a batch job
- -A 6-service pipeline (ingestor, NATS, TimescaleDB writer, strategy engine, gateway, dashboard) needs distributed tracing to stay debuggable
- -Docker images must stay lean β distroless Go builds across all services
Architecture
Multi-service streaming pipeline: a Go ingestor publishes telemetry events onto NATS JetStream, which fans out to a TimescaleDB writer maintaining hypertables and continuous aggregates for fast time-range queries. The strategy engine consumes the same stream, running a two-piece linear tire degradation model and fuel-corrected lap projections to evaluate undercut/overcut windows against the pit-lane delta. A Rust module explores strategy variance via Monte Carlo simulation. gRPC connects internal services; a WebSocket gateway pushes live strategy state to the React dashboard, which renders tire-life timelines with D3.js. The stack runs as a 6-service Docker Compose deployment with distroless Go build images, and every service emits OpenTelemetry traces, metrics, and logs to Jaeger, Prometheus, and Grafana.
Tech Choices & Why
NATS JetStream
Persistent, replayable pub/sub between the ingestor and downstream consumers (TimescaleDB writer, strategy engine) without coupling them directly.
TimescaleDB hypertables + continuous aggregates
Telemetry is fundamentally time-series data; continuous aggregates keep tire-life and lap-time queries fast as history grows.
Rust for the Monte Carlo module
Strategy variance simulation is CPU-bound; Rust keeps it fast without blocking the Go services.
OpenTelemetry across every service
A 6-service pipeline is hard to debug without distributed tracing from ingestion through to the dashboard.
Key Metrics
Pipeline
Go -> NATS -> TimescaleDB
Services
6-Service Compose
Observability
OTel + Grafana
Challenges & Solutions
Problem
Strategy recommendations need to reflect live tire wear and fuel load, not a static pre-race model.
Solution
The strategy engine recomputes tire degradation and fuel-corrected lap projections on every telemetry tick consumed from NATS JetStream, rather than running as a periodic batch job.
Problem
Debugging a 6-service pipeline (ingestor, NATS, TimescaleDB writer, strategy engine, WebSocket gateway, dashboard) is difficult without visibility into where time is spent.
Solution
OpenTelemetry traces, metrics, and logs from every service, visualized in Jaeger and Grafana with Prometheus as the metrics backend.
Trade-offs
- ~Two-piece linear tire degradation is an approximation, not a full physics-based tire model β sufficient for strategy calls, not for tire engineering.
- ~NATS JetStream adds an extra hop versus a direct database write, but decouples ingestion from strategy computation.
Impact
6-service Docker Compose deployment with distroless Go builds and GitHub Actions CI (golangci-lint, testify, testcontainers-go). Demonstrates a full streaming-telemetry pipeline β ingestion, durable pub/sub, time-series storage, real-time strategy computation, and live dashboard delivery β fully observable via OpenTelemetry.
What I'd Improve
- +Add historical race replay mode for post-race strategy analysis
- +Expand the Monte Carlo model to account for safety car probability
- +Add multi-driver comparative strategy views
This project was reviewed by Luka (Principal Research Consultant) and Nala (UI/UX Compliance Auditor). They had no comments, which we interpret as approval.