Skip to content
Aadil Salman Butt
← All work
Case study 03

Personal projectCode and write-up

ApexFlow

A machine learning pipeline that predicts Formula 1 lap times and retrains itself every race week. A new model replaces the current one only when it scores better.

  1. Race dataFastF1
  2. Validation and DVCschema checks, versions
  3. TrainingXGBoost, LightGBM, MLflow
  4. Model registrypromote if better
  5. FastAPIprediction plus uncertainty
  6. DashboardReact, Grafana
Role
Data pipeline, modelling, serving and monitoring
Timeline
Dec 2025 to Mar 2026
Stack
Python, XGBoost, Airflow, MLflow, FastAPI, Docker
Scale
35 commits, 3 Docker images

The problem

Lap times shift between practice, qualifying and the race, so a model trained once goes stale within a weekend. A notebook can't keep up with that.

The requirement: retrain on each new race without a person in the loop, and never ship a model that is worse than the one already serving.

What I built

01

Versioned, validated data

Race data is schema-checked before training and versioned with DVC, so any model can be traced back to the exact data it saw.

02

The weekly retrain-and-promote loop

Airflow pulls the latest race, retrains XGBoost and LightGBM models tuned with Optuna, and logs each run to MLflow. A candidate is promoted only if it beats the current model.

03

Inference and monitoring

A FastAPI service returns each prediction with an uncertainty estimate to a React dashboard. Prometheus, Grafana and Loki track accuracy and drift.

How it fits together

Airflow drives the loop from race data to the dashboard, and Grafana watches every step.

  1. Race dataFastF1
  2. Validation and DVCschema checks, versions
  3. TrainingXGBoost, LightGBM, MLflow
  4. Model registrypromote if better
  5. FastAPIprediction plus uncertainty
  6. DashboardReact, Grafana

Decisions and trade-offs

Promote only on improvement

Automatic retraining is only safe if a worse model can never replace a better one. Every candidate is scored against the current model before promotion.

Trade-off: a sudden regime change can leave an older model serving until a new one wins.

Report uncertainty with each prediction

A lap time without a range invites false precision. Each prediction comes with an interval so a reader knows how far to trust it.

Trade-off: more compute per request and a more complex response.

Free-tier deployment across three hosts

The dashboard is on Vercel, the API on Render and the database on Supabase, which keeps the whole system free to run.

Trade-off: cold starts on the API and three dashboards to watch.

Results

3
Docker images: pipeline, inference and dashboard
35
commits
Weekly
retrain on the latest race
Next case studyJunket Tours