Formula 1 · race strategy · every race since
How are races won with tyres and pit stops?
The fastest car does not always win. Teams decide which tyres to fit and when to stop for new ones, and a good call is worth more than raw speed. pitwall downloads every Formula 1 race, models it, and turns it into answers anyone can follow — no F1 knowledge needed.
01The answers, on six pit boards
A pit board is the sign a team holds out from the pit wall to tell its driver what matters right now. These are the six things the data says matter most. Each is explained further down.
is what a pit stop costs: the median time in the pit lane under normal racing. The tyre change itself takes under three seconds — the rest is driving slowly past the garages.
of finishers stop exactly once,
is what a soft tyre loses every lap as it wears; a hard one loses
of the time, pitting before the car ahead gets you past it. Fresh tyres are quick, but usually not quick enough:
of all race stops are made while the race is neutralised. Everyone drives slowly then, so a stop costs far less — teams wait for it if they can.
of races are won from first on the grid, and
Race figures use the
02Race explorer
Pick any race. The first chart is its strategy: each row is a driver, in finishing order; each coloured bar is a stint — the laps driven on one set of tyres, marked with the tyre's letter; white diamonds are pit stops. The second is the lap chart: every driver's position at the end of each lap, from the starting grid to the flag.
· , · won by
Lap chart position at the end of each lap · team colours, the second driver of a team dashed · dots are pit stops
Result “typical lap” is the median of the driver's clean laps
Stops made under the Safety Car or a red flag cost much less time, so they are drawn hollow. Some
03Tyres: fast or lasting, never both
There are three dry-weather tyres. Soft grips best and wears out soonest; hard is slower and lasts; medium sits between. As a tyre wears, each lap gets slower. To see that wear we compare every clean lap with the average of the same driver's stint — which removes how fast the car and driver are — and take the median at each tyre age.
: how much slower each lap gets
Cars also get lighter as they burn fuel — about
How long a set lasts middle half of all race stints, and the median
Wear per lap, all circuits median race stint, fuel-corrected
What each circuit is raced on share of race laps by tyre, hardest-wearing circuits first
A circuit raced mostly on hard tyres is one that destroys soft ones: long fast corners, rough tarmac or heat. Wet-weather tyres are left out of this chart.
04Pit stops: twenty seconds you never get back
A stop has two parts. The pit lane has a speed limit, so driving through it costs time however good the crew is — and how much depends on the circuit. The stationary time is the crew's part: lifting the car and changing four wheels.
The price of a stop, by circuit median seconds in the pit lane under green flag
Fastest crews median seconds stationary · the source publishes it from 2024
Waiting for the cheap stop share of race stops made while neutralised
Circuits with fewer than 10 timed stops and teams with fewer than 15 are left out. Where the pit lane is long the whole strategy changes: a stop that costs 30 seconds is worth avoiding in a way a 19-second one is not. Bars are in the team's own colour, with the name beside them.
05The undercut: does pitting first work?
Overtaking on track is hard, so teams try to pass in the pits. The undercut is the classic move.
A is faster but cannot get past B on track.
On fresh tyres A laps much faster than B, who is still on worn ones.
When B stops one to three laps later, has A gained enough to come out in front?
By how long the rival waited laps between the two stops · % worked · attempts
By season % worked · attempts
By team teams with 8 or more attempts · % worked · attempts
An attempt is counted when the car directly ahead pits one to three laps after the attacker. Only positions are used, not the time gaps between cars, and the rival may have had reasons of their own to stop. Stops during a red flag are excluded; stops under a Safety Car are hidden by default because everyone pits together then.
06Does the grid decide the race?
The grid is the starting order, set by the fastest laps in Saturday's qualifying. If strategy mattered little, everyone would finish where they started. Each square counts the drivers who started in one place and finished in another: the brighter diagonal is “finished where they started”.
Started here, finished there classified race finishes
Where winners start races with a published grid
Only classified finishers of full races with a published grid are counted (the field grew from 20 to
08The pipeline: one lap of the data
Every Monday morning after a Grand Prix, a scheduled job drives this lap once: from the public API to this page. Nothing here is computed by hand, and no key or password exists anywhere in it.
What each stage guarantees
- Ingest waits for the API's rate limit instead of hitting it, and re-running a weekend never duplicates data: a marker file is written last, so half-written weekends are never read.
- The lake is the source of truth: the warehouse can be rebuilt from it at any time without calling the API.
- dbt states what one row is in every model, and tests it. Impossible values stop the run; the site keeps its last good version.
- The site is built from exported files by a job with no cloud permissions at all.
Built with
| Ingestion | Python, httpx, pyarrow |
| Storage | Google Cloud Storage (Parquet), BigQuery |
| Transformation | dbt |
| Orchestration | GitHub Actions: weekly schedule, CI on every pull request |
| Infrastructure | Terraform, Workload Identity Federation (no keys) |
| Site | Observable Framework, Observable Plot |
| Cost | 0 per month: everything fits the free tiers, with a budget alert and a query quota |
09Decisions worth explaining
Every durable choice is written down with its context and the alternatives that lost. The full records are in the repository.
A lake first, and our own extractor
Raw files are kept exactly as received, so every later step can be replayed. A small hand-written extractor teaches rate limiting and idempotency better than a connector hides them.
Reload everything, every time
The data is megabytes, and BigQuery load jobs are free. Rebuilding the raw tables in full is simpler than tracking what changed and cannot drift.
Two cloud projects
Development and production share nothing: a mistake in one cannot touch the other, and each has its own budget alert.
GitHub Actions as the scheduler
One weekly job does not need a workflow engine running all week. Runs are public, free, and log in to the cloud with short-lived identities.
A static site, not a BI server
The site is files: nothing to keep running, nothing to pay for, and no credential near the public.
Report tables in dbt, a story and a BI page
What the site shows is decided in tested SQL, one grain per table; the export only copies. The page tells the story, the BI page lets you slice it.
10Quality
A dashboard is only as good as what stops a wrong number from reaching it.
What is checked
- Over 70 Python tests run without network or cloud: the extractor is tested against recorded answers of the real API.
- Over 110 dbt tests: keys are unique, references exist, values are in range, and the racing rules (what counts as an undercut, how wear is measured) are pinned by unit tests.
- Every pull request builds the models in throwaway datasets and builds this site before it can merge.
- Rows that fail a data-quality rule are stored in an audit dataset, so a warning can be inspected instead of guessed at.
What the source gets wrong, and what we do
- Messages worded by hand. Safety Car and red-flag messages change wording between seasons; unknown wordings raise a warning so they get added.
- No pit timing in some
races. Stops are inferred from tyre changes and shown without timing. - Broken stint records. A few stints have missing or inverted lap ranges: reported, and kept out of the tyre statistics.
- Gaps in lap timing (mostly lap 1 and pit laps) stay empty rather than being filled in.
How complete each race's data is — laps timed, pit timing official or inferred, grid published — is on the BI page.
11Limits, stated plainly
- Positions, not gaps. The undercut and the lap chart use the order of the cars, not the seconds between them.
- One fuel assumption. The same correction for every car and circuit; real cars differ a little.
- Strategy is not the only reason. A team may stop because of damage, a slow puncture or a penalty; the data cannot tell.
- Races and Sprints only. Qualifying and practice are not modelled, and nothing here uses car telemetry.
- An unofficial source. OpenF1 is a community API. It has gaps, and it changes; the pipeline documents and works around them rather than hiding them.
12Run it yourself
The whole project — code, infrastructure, tests, decisions and this site — is public.
# the extractor against a local folder: no cloud account needed git clone https://github.com/TomasRipsky/pitwall.git && cd pitwall make setup && make test PITWALL_LAKE_URI=.lake make ingest ARGS="--meeting 1255" # with a Google Cloud project (free tier): infrastructure, load, models, site make apply && make ingest ARGS="--season 2025" && make load && make transform && make site-preview