Distribution fitting and Extreme Value Theory
Meb Keflezighi won the 2014 Boston Marathon in 2:08:37. Sabastian Sawe's world record, 1:59:30, is 9 minutes 7 seconds faster than that, and off the fast end of the whole 31,842-runner field: 2.4 standard deviations below the mean. The median finisher took 94% longer than the record.
Median finish time. The field is close to log-normal, with a mean of 4:03 and a slow tail running out to the 7:00 cut-off.
Finishers faster than 1:59:30. The closest was the winner, at 2:09.
Generalized Pareto shape on the fastest 5%. Below zero, so the fast tail has a finite end.
Share of the field a 3:00 marathon finishes ahead of. A 4:00 is ahead of 43.2%.
Start · the question
I have run 14 marathons, with a best of 2:48 in Berlin. Put a club runner's time and the world record on the same time axis and they become two points on one curve: the curve a whole marathon field makes.
The curve here is the 2014 Boston Marathon, from the public llimllib/bostonmarathon mirror. I kept runners only (no wheelchair or handcycle entries) with times between 2 and 7 hours, which leaves 31,842 finishers.
Body · log-normal fit
A shifted log-normal with its floor at 118 minutes tracks the histogram closely. The median is 3:52, and the slow tail pulls the mean to 4:03 (standard deviation 51 minutes). The shape is lopsided: a runner can finish hours behind the middle of the field, while the winner was 1:43 ahead of it. Then there is the gap on the left, between the record and the winner, where nobody in the field ran.
Nobody in the field ran inside the gap between 1:59:30 and 2:09
Hover the chart, or focus it and use the arrow keys, to read a bar.
tables/web_continuum.json, written by
export_web.py from the file analyze.py reads.Tail · Peaks-Over-Threshold
Generalized Pareto shape, fitted to the 1,593 finishers under 2:56.
The body fit says little about the extreme fast end, so the tail gets a model of its own. I set the threshold at the fastest 5% of the field (2:56), measured how far each of those 1,593 runners beat it, and fitted a generalized Pareto distribution to those gaps. The shape parameter is −0.147.
A negative shape means the distribution is bounded: fast performances stop at some finite point. Peaks-Over-Threshold can tell whether such a bound exists but is poor at saying where it is, so I report the shape and leave out any estimate of a fastest possible time.
analyze.py.Lookup · your race
Enter a marathon time and, if you like, narrow the comparison to your gender and Boston's age group. The share is counted directly from the finishers, one-minute bins, with no fitted curve involved.
h:mm:ss or h:mm, between 2:00 and 7:00
For reference, the fixed rows in tables/you_vs_goat.csv, printed
as a pace band. Each cell gives a finish time, the share of the field behind
it, and how much longer it takes than the record.
A 4:00 marathon takes just over twice as long as the record.
Limits · one field, one year
Boston is a qualifying race, and almost everyone in this field had to run a qualifying time to enter, so the curve sits faster than a general-entry marathon would. When the lookup says a 3:00 is ahead of 92.6%, it means ahead of this field; a slower field would push the record further out. The age-group comparison inherits the same bias, because Boston's qualifying times loosen with age.
The field is one race in one year, Boston 2014. The 2013 race is left out because it was stopped partway through.
I don't give the record's rarity as "1 in N". That needs the fitted density far past the last data point, so the record is described by what was observed: faster than all 31,842 finishers and 2.4 standard deviations below the mean.
The record used is Sabastian Sawe's 1:59:30 (London, 26 April 2026), which
World Athletics ratified on 23 July 2026; it is the value
set in analyze.py. It replaced Kelvin Kiptum's 2:00:35, and the
change moved the record mark and the percent-slower figures and none of the
field statistics.
Finish · how it was built
scipy.stats.lognormscipy.stats.genpareto)export_web.py writes one-minute histograms by gender and age group and the log-normal curve to tables/web_continuum.json