Kimball star layout written by the ingest script:
data/parquet/f1/
dims/
drivers.parquet
constructors.parquet
circuits.parquet
races.parquet
facts/
season=2025/
results.parquet
laps.parquet
pit_stops.parquet
qualifying.parquet
cd /Users/kareem/Documents/Projects/Personal/Pitwall
npm installnpm run ingest -- --seasons 2025Then validate:
npm run partitionUnauthenticated API (docs):
- Burst: 4 requests / second
- Sustained: 500 requests / hour
This project defaults to 8 seconds between live requests so a full season (~350–450 calls including lap pages) stays under the hourly cap.
Expect ~50–70 minutes for a cold 2025 ingest (laps are the expensive part).
- Stop the script (Ctrl+C) if it is stuck retrying.
- Wait ~30–60 minutes for the hourly window to recover.
- Re-run the same command:
npm run ingest -- --seasons 2025Successful responses are cached under data/cache/jolpica/, so re-runs skip already downloaded pages and only fetch what is missing.
| Variable | Default | Meaning |
|---|---|---|
JOLPICA_MIN_INTERVAL_MS |
8000 |
Delay between live HTTP calls |
JOLPICA_NO_CACHE=1 |
off | Force refetch everything |
JOLPICA_CACHE_DIR |
data/cache/jolpica |
Cache location |
DATA_DIR |
data/parquet/f1 |
Lake root |
Faster (risks 429):
JOLPICA_MIN_INTERVAL_MS=3000 npm run ingest -- --seasons 2025- Fetch season calendar, drivers, constructors
- Per round: results, qualifying, pit stops, paginated laps
- Stage in DuckDB, validate grain uniqueness
- Merge/upsert dims Parquet
- Replace facts/season=YYYY/ Parquet (idempotent)
Natural keys only (driver_id, constructor_id, circuit_id, season+round).