625/s
uploads at the Sunday-morning peak
Strava has 200 million athletes. Assume 10 million uploads a day, about 120 a second on average, and five times that when long runs finish.
Where does the work happen?
Bad: In the upload request
A slow dependency fails the upload; retries add load and duplicates.
Good: Store, 202, queue
Store the raw file, enqueue, reply in ≈150 ms. Workers catch up.
Assume 40 million segments. Which did you just ride?
Testing them all takes 40 s per run. Instead, cover the track with map cells and look up segments that start there.
Thousands of efforts a second from uploads, deletes and privacy changes. Every board must end up exactly right.
The trick
Key changes by segment + athlete. Events say only “something changed”; the consumer re-reads the truth.
15×
smaller as a columnar Parquet lake
150 TB of per-activity JSON became 10 TB. A full scan went from ≈ $5,000 in requests to about an hour on 30 machines.
2018: a fitness heatmap lit up military bases
Heat counts runs, not people. Thirty soldiers looping one base glow as bright as a busy park, and in an empty desert that’s attributable.
The fix: count people, not runs
- Hide cells with fewer than k distinct athletes
- Rebuild monthly over a two-year window
- Street-level zoom only for signed-in athletes
Remember
Accept fast, process async, fan out events. Correctness lives in keys and re-reads; privacy lives in the aggregate.