The PaceWise race projection model
Every algorithm PaceWise uses to turn a runner's results into projected race times, age grades, splits and pacing plans, in mathematical terms, with the constants and the sources.
Edition 1, June 2026. Published here 16 September 2026. Open for review.
Most race predictors take one result and one textbook curve. The PaceWise model (section 3) blends every result a runner has logged, each with its distance, time and date, into a personal projection band at the target distance: it fits the runner's own fatigue exponent, weights each result by how recent it is and how close its distance sits to the target, and widens the band when the evidence disagrees or has to stretch far. It is closed-form, deterministic, runs offline, and reduces to Riegel when the data can only support that.
The classical single-result models (section 2), the pacing curve (section 4) and WMA age grading (section 5) are specified alongside it so the whole calculation surface can be checked as one. This page is written for a reader with a sports-science or applied-maths background who wants to check the formulas against the literature. Corrections are welcome: support@doughworks.dev.
Notation. Times are in seconds (t), distances in metres
(d), pace in seconds per metre. ln is the natural logarithm. All
models are pure, deterministic and offline. Non-positive or non-finite inputs raise a typed
error rather than returning NaN or infinity (section 6).
Contents
- Foundations: the pace identity
- Classical race-equivalence models
- The PaceWise model
- Pacing-plan curve
- WMA age grading
- Numerical-safety contract
- How it is checked
- Constants at a glance
- The goal-readiness verdict
1Foundations: the pace identity
All elementary conversions are the single identity
t = p · d p = t / d d = t / p v = 1 / p
with t seconds, d metres, p seconds per metre and
v metres per second. Display units (min/km, min/mile) are applied at the
surface; the core is unit-free canonical SI. There is nothing to validate here beyond
dimensional consistency and the guard rails of section 6. It is listed because every higher
model reduces to it.
Session aggregate. For segments (ti, di) the
total is T = Σti, D = Σdi, average pace
T/D. Each segment must be individually positive: a negative leg is rejected,
never allowed to cancel another into a plausible total.
2Classical race-equivalence models
Given one known performance (t₁, d₁), predict the time
t₂ at a target distance d₂. PaceWise offers three textbook models
so a runner can cross-check; they are also the fallback whenever only a single result
exists. A fourth option (2.4) applies the same single-result form with the runner's
own fitted exponent. It belongs in this section rather than section 3 because it
too is a pure function of one performance. The race time
predictor runs the three textbook models side by side.
2.1Riegel power law
Peter Riegel's endurance model (Riegel, American Scientist, 1981):
t₂ = t₁ · (d₂ / d₁)^k
k is the fatigue exponent. k = 1 would mean pace is
independent of distance; real endurance running has k > 1 because
sustainable pace fades as distance grows. The literature value, and the default here, is
k = 1.06: the canonical exponent for roughly 1.5 km to 42.2 km and the constant
behind most public race predictors.
Cross-check. A 20:00 5K (1200 s) to 10K gives
1200 · 2^1.06 = 2502 s = 41:42, matching Omnicalculator's race predictor and
The Running Genie to the second.
2.2Cameron model
David Cameron's fitted model is steadier than Riegel over long extrapolations. With
distances in miles (d̃ = d / 1609.344):
t₂ = (t₁ / d̃₁) · d̃₂ · a(d̃₁) / a(d̃₂) a(x) = 13.49681 − 0.048865·x + 2.438936 / x^0.7905
a(x) is an empirical per-mile cost curve. It crosses zero near 277
miles (about 446 km); beyond that the fit is meaningless, so the model rejects the
target rather than return a negative or spuriously positive time.
Cross-check. 20:00 5K to 10K under Cameron is 2499.66 s (about 41:40), within half a second of the closed-form value, and within 5% of Riegel on a one-octave extrapolation.
2.3Daniels & Gilbert VDOT
A VO₂-based physiological model (Daniels & Gilbert, 1979). For a race of
d metres in t seconds, let m = t/60 minutes and
velocity v = d/m in metres per minute:
VO₂(v) = −4.60 + 0.182258·v + 0.000104·v² (oxygen cost of pace)
%sustainable = 0.8 + 0.1894393·e^(−0.012778·m)
+ 0.2989558·e^(−0.1932605·m) (fraction of VO₂max held)
VDOT(d, t) = VO₂(v) / %sustainable
The runner's VDOT is fixed by the known race. The equivalent time at the target is the
t₂ that reproduces that same VDOT. VDOT(d₂, ·) is
monotonically decreasing in time over the positive-VO₂ region. VO₂(v)
goes negative below about 25 m/min (a 6.7-hour 10K), so strict global monotonicity fails
only at implausibly slow paces well outside any real target. Within the region every real
target occupies the root is unique, so it is found by bisection over
[1 s, 86 400 s]: 100 halvings, far below the 1 µs tolerance. A target whose
equivalent falls outside the 24-hour bracket is rejected rather than silently saturated.
The VDOT calculator shows both equations with a worked
example.
Cross-checks. From a 22:00 5K (VDOT about 45, per Jack Daniels' tables): 10K about 45:40 (2740 s, ±15 s), half marathon about 1:40:30 (6030 s, ±60 s), marathon about 3:30:00 (12 600 s, ±30 s).
2.4PaceWise per-result equivalence
The equivalent-times surface offers the PaceWise model in the same single-result form as the three textbook models: the plain power law
t₂ = t₁ · (d₂ / d₁)^k
with k the runner's fitted, trust-shrunk fatigue exponent of 3.1,
fitted once from the full per-distance frontier and then applied to the one result being
converted. A runner with fewer than two distinct distances gets the Riegel default
k = 1.06, so the option degrades to 2.1 exactly. Unlike the three formulas, the
conversion carries a band: the stance α ∈ [−1, +1] sweeps
t₂(α) = t₂ · exp(−α · σ), σ = min( σ_min + β · |ln(d₂/d₁)|, σ_max )
which is the 3.4 width with the variance term identically zero. A single result cannot
disagree with itself, so only the extrapolation floor (σ_min = 0.01,
β = 0.015, capped at σ_max = 0.10) contributes, and the band is
log-symmetric exactly as in 3.4.
The proven-best floor of 3.5 is deliberately absent here. Equivalence describes one result: what that run is worth at another distance, a pure function of it. The floor's job is to keep a projection of the runner from contradicting proof. Flooring the equivalence would re-couple every result's table to the whole stored history, exactly the blending this per-result form exists to avoid. When the runner's stored best at the target already beats the conversion, the apps draw the comparison beside the number (a "Your PB" badge) instead of folding it in.
The supplied exponent is rejected if non-finite, never silently defaulted, then
defensively clamped to the physiological [1.02, 1.15] range of 3.1.
Validation. From the device-reported fixture of 3.1 (5K 1331 s, 10K 2733 s, half
6594 s, aged 61, 61 and 75 days) the fit gives k ≈ 1.0677, and the half
converts to a 10K of 2971.6 s, about 49:32 (stance ±1 gives 48:29 and 50:35).
Deliberately not floored at the stored 45:33 10K. The test suite also pins that
k = 1.06 reproduces 2.1 verbatim, that the band is log-symmetric
(t(−1)·t(+1) = t(0)²), the single-result fallback, the exponent clamp, the
band ceiling under extreme stretch, and the section 6 rejection cases.
Reviewer note. The three textbook models are intentionally redundant; the suite asserts they sit within 5% of one another on a one-octave extrapolation. Divergence grows with extrapolation distance, which is exactly the motivation for the PaceWise model.
3The PaceWise model
The contribution. Where section 2 extrapolates from a single performance, PaceWise blends every result a runner has logged, each with its distance, time and optional date, into a personalised projection band at the target, swept by an aggressiveness stance. It is fully closed-form (no iteration), deterministic, and reduces gracefully to Riegel when the data can only support that.
Inputs: a set of results {(ti, di, ai)},
where ai is the result's age in days before the reference
date (ai < 0 means undated); a target distance D;
and an aggressiveness stance α ∈ [−1, +1]. Output: a projected time at
D.
The model has three stages, plus a proven-best floor on the output (3.5).
3.1Stage 1: the personal fatigue exponent
Rather than assume Riegel's k = 1.06, PaceWise fits the runner's own
k from the slope of ln t against ln d. Taking logs
of the power law t = c·d^k gives the linear relation
ln t = ln c + k · ln d,
so k is the slope of a least-squares line through the runner's results in
log-log space. Two refinements:
- Per-distance frontier. Only each distinct distance's fastest result is fitted (group by rounded metres, keep the minimum time), so slow repeats of one distance do not masquerade as fatigue.
- Recency weighting. Each frontier point carries the fit weight
wifit = r(ai), the recency decay of 3.2, so the slope tracks current fitness. Stages 2 and 3 use a different weightwiblend, recency × proximity; the two are kept distinct deliberately.
The weighted least-squares slope is
Σ wᵢ^fit (xᵢ − x̄)(yᵢ − ȳ)
k = ────────────────────────────── , xᵢ = ln dᵢ, yᵢ = ln tᵢ,
Σ wᵢ^fit (xᵢ − x̄)²
with weighted means x̄ = Σwᵢ^fit·xᵢ / Σwᵢ^fit and
ȳ = Σwᵢ^fit·yᵢ / Σwᵢ^fit.
Fallbacks and clamps.
- Fewer than two distinct distances: no slope, so
k = 1.06. - Weighted variance
Σwᵢ^fit·(xᵢ−x̄)² / Σwᵢ^fit < 10⁻⁴(distinct distances within about 2% of each other, numerically unstable):k = 1.06. Dividing byΣwᵢ^fitmakes the threshold scale-invariant. It no longer shifts with the absolute weight magnitude, so two runners with the same distance spread but differently aged results get the same fit-or-fallback decision. - Otherwise
kis clamped to the physiological range[1.02, 1.15].k = 1.0would be no fatigue at all; above 1.15 is steeper than real endurance running.
Fit-quality shrinkage. A slope that survives the guards above is still only
trusted as far as the frontier actually agrees on it. Let k_ls be the raw
least-squares slope (before the clamp) and define the fit's weighted residual
variance in log-time,
v = Σ wᵢ^fit · ( (yᵢ − ȳ) − k_ls·(xᵢ − x̄) )² / Σ wᵢ^fit ,
the scatter of the frontier about the line the fit actually drew. The clamped slope is then shrunk toward the Riegel default in proportion to that scatter:
trust = τ / (τ + v), τ = 10⁻⁴, k = 1.06 + trust · ( clamp(k_ls, 1.02, 1.15) − 1.06 ).
τ is the residual variance at which the personal slope earns exactly half
trust; in log-time, v = 10⁻⁴ corresponds to residual scatter of about 1% in
time. No re-clamp is needed: the result interpolates two values already inside
[1.02, 1.15]. Three properties matter for review:
- Clean fits are untouched.
v = 0gives trust 1, so a frontier one power law explains exactly returns the unshrunk slope bit-identically. This includes every frontier of exactly two distinct distances (a line through two points has zero residuals), so the model's two-result behaviour is unchanged. - Weight-scale invariance. Like the minimum-variance guard above,
vis a variance (divided byΣwᵢ^fit), not a raw weighted sum, so the trust decision does not shift when a runner's results all age together. - Residuals are measured against the raw slope, not the clamped one. The question is how well one power law explains the frontier, and the raw least-squares line is the best such law; measuring scatter about the clamped slope would conflate fit quality with clamp distance.
The motivation: wᵢ^fit is recency-only, so unlike the blend, whose proximity
factor (3.3) halves a far result's vote per distance-doubling, a lone far-distance result
enters the slope fit at nearly full weight, and because the exponent is shared by every
candidate it can drag the entire blend, unopposed. In the device-reported case
that motivated the mechanism, one weak half marathon beside a consistent 5K and 10K
steepened k to 1.112 and pushed the raw 10K blend 61 s slower than the
runner's proven 10K. Under shrinkage that frontier's scatter (v ≈ 5.8·10⁻⁴)
earns the fitted slope only 0.15 trust, k settles at 1.068, and the projection
recovers a usable band (the 3.5 floor still pins the likely time at the proven best).
The fitted exponent is also exposed on its own, the identical value the blend fits internally, so the per-result equivalence of 2.4 converts through the same personal profile the projection uses.
Validation. Three results placed exactly on a k = 1.10 law project a
fourth distance back onto that law to a relative error below 10⁻⁹ (an exact law has
v ≈ 0, so shrinkage leaves it alone). Separate cases exercise the implausible
exponent clamp, the repeats-of-one-distance and near-identical-distance fallbacks, and the
scale-invariant variance threshold. The shrinkage is pinned by the device-reported shape
above (a lone weak outlier no longer collapses the same-distance band), by two-distance
frontiers keeping full trust, by a lone strong outlier still speeding the
projection (the correction is symmetric, not slow-biased), and by the trust decision
surviving a common ageing of the results.
3.2Recency weighting
A result's vote decays exponentially with age, half-life H = 180 days:
r(a) = exp(−ln2 · a / H), a = aᵢ if aᵢ ≥ 0 and finite, else H.
So a six-month-old result counts half as much as today's. An undated result is pinned at
exactly one half-life: kept as evidence at half a vote, but unable to outvote a fresh dated
result. The aᵢ ≥ 0 guard folds a future-dated result (negative age
relative to the reference date) into the same undated bucket; the two are indistinguishable
to the model, which is acceptable since a future race date is not a meaningful input
here.
Why 180 and not 365. Fitness moves on a months-to-seasons timescale, but a
one-year half-life let evidence a runner had visibly outgrown keep a third to a half of the
blend. A 17-month-old half marathon still held 36% of the vote at its own distance, and a
runner mid-breakthrough had months of gains averaged against the form they started with.
Halving H corrects those without touching a runner whose results agree with
each other, and it strengthens the mirror case: where a fresh same-distance result
genuinely is the best evidence, its share rises from 69% to 78%. Reweighting by
distance instead was measured and rejected.
Why not shorter. Below roughly 120 days the model begins projecting long races
from short-distance speed alone while simultaneously narrowing the band, because a
dominant single candidate has nothing left to disagree with it. A sharp 5K and 10K pair six
months on from a real 3:45 marathon projects 2:58 at a 60-day half-life: 47 minutes
faster than the runner has ever raced, in a band 20 minutes tighter than the current one.
That is the confident-nonsense failure the σ_min + β·s̄ floor (3.4) exists to
prevent, and the half-life must not undo it. 180 days sits with room on both sides.
3.3Stage 2: evidence blending (the likely time)
Every result is projected to the target D through the personal power law,
in log-time space, where race times compose multiplicatively, so the natural average
is geometric and the band is symmetric. Define each candidate's log-time and its weight:
sᵢ = ln(D / dᵢ) (the "stretch": log-distance to target) ŷᵢ = ln tᵢ + k · sᵢ (result i's projection of D, in log-time) wᵢ^blend = r(aᵢ) · exp(−|sᵢ|) (recency × distance-proximity)
This blend weight is distinct from the fit weight wᵢ^fit of 3.1: the fit
tracks fitness over time (recency only), while the blend additionally trusts
nearby races more. The proximity factor exp(−|sᵢ|) means a result
one distance-doubling away carries half the vote of one at the target distance.
Near evidence dominates far evidence. The likely log-time is the weighted mean
μ = Σ wᵢ^blend·ŷᵢ / Σ wᵢ^blend,
and the likely time is exp(μ): a recency- and proximity-weighted
geometric mean of the individual projections.
Sanity. A single result at the target returns itself exactly; a single result off target reduces to plain Riegel at 1.06. Recency dominance, the reduced vote of undated results, and proximity dominance are each pinned by a test.
3.4Stage 3: the stance band
The weighted spread of the candidates measures how much the runner's own evidence
disagrees about D:
σ² = Σ wᵢ^blend·(ŷᵢ − μ)² / Σ wᵢ^blend (weighted variance of the log-projections)
This is floored by an uncertainty that grows with how far the evidence had to extrapolate, and capped so a wildly disagreeing set still yields a usable band:
s̄ = Σ wᵢ^blend·|sᵢ| / Σ wᵢ^blend (mean stretch) σ = min( max( √σ², σ_min + β · s̄ ), σ_max ) (floor first, then ceiling) σ_min = 0.01 (±1 % floor at zero extrapolation) β = 0.015 (extra half-width per unit of |ln(D/d)|) σ_max = 0.10 (±10 % ceiling)
The floor-then-ceiling order is load-bearing. Past s̄ = (σ_max − σ_min)/β = 6,
reachable only by extreme extrapolation (a 100 m result projected to the marathon has
s̄ = ln(421.95) ≈ 6.05), the floor σ_min + β·s̄ exceeds the
ceiling σ_max, and the outer min pins σ to σ_max. A
three-argument clamp(value, lo, hi) with lo > hi is
undefined (it would throw), so an implementation must apply the ceiling last, not
nest the two bounds.
The stance α sweeps the band log-symmetrically:
t(α) = exp( μ − α · σ ), α ∈ [−1, +1] (clamped; non-finite ⇒ 0).
α = 0 is the likely time, α = −1 conservative (slower),
α = +1 aggressive (faster). Because the sweep is linear in log-time, the band
is symmetric in the multiplicative sense:
t(−1) · t(+1) = t(0)² (conservative × aggressive = likely²)
Validation. The identity above is pinned to relative 10⁻⁶. Further cases pin that conservative is slower and aggressive faster, that the stance clamps beyond the band, that a non-finite stance reads as likely, that the band widens with extrapolation (5K to marathon wider than 5K to 10K), and the floor-versus-ceiling inversion at extreme extrapolation (100 m to marathon). The log-symmetry identity holds while the proven-best floor (3.5) is slack; when the floor binds it wins.
3.5The proven-best floor
The blend can produce a projection at a distance the runner has already raced that is slower than their own supplied best at that distance. A fresh 10K PB beside a comparatively weak half marathon drags the blended 10K projection below the proof. The fit-quality shrinkage of 3.1 bounds the exponent channel of that drag; the direct blend pull of the weak result remains, so the floored case still arises. Mathematically defensible (the other evidence genuinely argues current endurance is worse), but as a product number it undermines trust: "you'll likely run 49:49" under a just-logged 49:16 reads as a bug, not a nuance. So the model floors its output at the fastest supplied result at the target distance:
t_final(α) = min( t(α), min{ tᵢ : |ln(D / dᵢ)| ≤ 10⁻⁴ } )
Properties:
- Applies at every stance. Even the conservative edge may not read slower than
proof. When the floor binds it deliberately breaks the 3.4 log-symmetry identity
(
t(−1)·t(+1) = t(0)²holds only while the floor is slack) and can collapse part of the band onto the proven time. Proof beats symmetry. - Never speeds up a slack projection. A proven best slower than the blend
leaves the blend untouched (
minonly ever lowers), so a stale or weak same-distance result cannot drag a faster projection down to it. - Distance matching is tolerant. "Same distance" means within
10⁻⁴in absolute log-distance (about 0.01%), so metre-rounding conventions across surfaces and platforms (a half marathon as 21 097, 21 097.5 or 21 098 m) cannot defeat the floor. This is far below the roughly 2% gap 3.1 treats as distinct distances. - Staleness stays the caller's concern. The floor considers exactly the results passed in. The apps' recency pooling (which sets aside PBs older than 18 months while fresher ones exist) has already vetted them, so an ancient proof only reaches the floor when nothing fresher exists at all.
Downstream the floor is a projection concept: the goal-readiness verdict (Appendix B) grades against the floored likely time, and the race surfaces publish the floored blend. The equivalent-times table does not consume the blend. It converts the single result on screen (2.4) and is deliberately unfloored there, the cross-result comparison being the UI's badge to draw. The pacing-plan curve (section 4) is untouched: it shapes a chosen goal time and never consumes the projection.
Validation. Tests pin the headline case (blend slower than a fresh 10K PB returns the PB), the slack direction (a slower same-distance best leaves the blend untouched), no off-distance leakage, the conservative edge of the band, and the 21 097.5 versus 21 098 m match.
3.6Design rationale
| Choice | Why |
|---|---|
| Log-time space throughout | Race times scale multiplicatively; a geometric mean and a log-symmetric band are the natural, scale-invariant operations. |
Personal k, clamped and trust-shrunk | Honours the runner's own fatigue signature when the data supports it, never leaves the physiological envelope or trusts an ill-conditioned fit, and hands a scattered fit back toward Riegel rather than letting one off-line result steepen every candidate. |
| Recency half-life 180 days | Fitness drifts on a months-to-seasons timescale. Half a season keeps stale PBs as weak priors without letting them dominate, and is short enough that evidence a runner has outgrown actually fades (3.2). |
Proximity exp(−|s|) | A 5K is weak evidence for a marathon. Weighting by log-distance encodes "trust nearby races more" without a hard cutoff. |
| Variance-driven band, floored by extrapolation | The band should widen both when the runner's results disagree and when the model extrapolates far, capturing both kinds of uncertainty in one width. |
Known limitations and open questions for review.
- The band is a heuristic uncertainty, not a calibrated statistical prediction
interval.
σ_min,βandσ_maxare chosen for sensible UX, not fitted to a coverage target. A reviewer may wish to assess empirical coverage against real longitudinal data. - The personal-
kfit uses fastest-per-distance points, discarding within-distance scatter. This trades statistical efficiency for robustness to junk data. Worth a second opinion. - Recency and proximity weights are multiplied independently. There is no interaction term: a recent and near result is not super-weighted beyond the product.
- An asymmetric disagreement in the evidence (one slow outlier) shifts the blend mean rather than widening the band. The fit-quality shrinkage of 3.1 bounds the exponent channel of that shift, but making disagreement widen σ itself remains an open tuning question.
4Pacing-plan curve
A pacing plan distributes a goal time T across the race with a signed
bias s (negative split versus positive split). With f the
fraction of distance covered, the fraction of goal time elapsed is
E(f, s) = f · (1 + s · (1 − f)), s ∈ [−0.06, +0.06].
Properties the maths guarantees, for any |s| < 1:
E(0,s) = 0andE(1,s) = 1: the plan always lands exactly on the goal time, regardless of bias.Eis monotonic inf: cumulative time never goes backwards.
s is clamped to ±0.06 (±6% peak deviation from even pace) so a generated plan
stays physically sensible. Cumulative split times are T · E(dm/D, s)
at each marker dm; the final row lands on T by
construction. The pace band generator prints this curve.
5WMA age grading
Age grading normalises a performance against the world-best standard for the athlete's
age and sex, using the World Masters Athletics (WMA) 2020 factor tables (compiled by
Alan Jones; encoded by the Runalyze age-grade project, CC BY 4.0). For a time
t over distance d by an athlete of given age and sex, with age
factor φ ≤ 1 and open-class standard S (both read from the
tables, linearly interpolated across the 28 standard distances):
age-graded time = t · φ (the open-class-equivalent "aged-up" time) age-grade % = (S / φ) / t · 100.
S/φ is the age standard: the world-best time expected at that age.
Ages outside the table's 5 to 100 range are clamped; distances outside the table's columns
use the nearest column outright (no extrapolation). The factor tables are machine-generated
for every platform from one upstream fetch, so the apps and the
age grade calculator cannot drift.
This section is strictly descriptive (it reports against a published standard). The only thing to validate is faithful table reproduction and correct interpolation, both unit-tested against published values.
6Numerical-safety contract
Every entry point enforces the same discipline, which a reviewer can rely on:
- Domain guards. Inputs that are zero, negative, non-finite or empty raise a typed
error (non-positive time, non-positive distance, empty results, and so on), never a
silent
NaNor infinity. - Result guards. Even finite inputs whose computation overflows (a Riegel ratio whose power exceeds double range, or a PaceWise projection that overflows) are rejected by a finiteness check on the output, rather than returned as infinity.
- No saturation masquerading as an answer. Bracketed solvers (VDOT) and fitted curves (Cameron) reject targets outside their valid domain instead of returning a clamped endpoint.
- Determinism. No randomness, no clock reads inside the maths (the reference date and result ages are passed in), no platform-dependent floating-point paths. One shared core is the single source of truth; the app, and the calculators on this site, are thin layers over it.
7How it is checked
The numbers quoted in the cross-check and validation boxes above are not illustrations. Each is a case in the core's test suite, which runs on every change on both the JVM and native targets. The apps call the same core, and the web calculators on this site run a line-by-line port of it that a build check re-tests against the core's own cases before anything deploys. A formula on this page, the number in the app, and the number in the browser cannot disagree without that check failing.
If you find a formula, constant or citation here that is wrong, or a case the model handles badly, email support@doughworks.dev. The core and its tests are the authoritative reference; this page follows them, and a correction that lands there will be reflected here with a new edition line.
AConstants at a glance
| Symbol | Value | Meaning |
|---|---|---|
k (default) | 1.06 | Riegel fatigue exponent, and the PaceWise fallback |
k range | [1.02, 1.15] | physiological clamp on the fitted exponent |
H | 180 days | recency half-life (and the assumed age of undated results) |
σ_min | 0.01 | band half-width floor (about ±1%)† |
β | 0.015 | extra band half-width per unit of log-distance extrapolated |
σ_max | 0.10 | band half-width ceiling (about ±10%)† |
| min weighted log-variance | 10⁻⁴ | below this (distances within about 2%) the exponent fit is abandoned |
τ (exponent fit trust) | 10⁻⁴ | weighted residual variance of ln t at which the fitted exponent earns half trust (shrunk toward 1.06) |
| same-distance tolerance | 10⁻⁴ | |ln(D/d)| within this counts as the distance for the proven-best floor |
pacing bias s | [−0.06, +0.06] | ±6% peak deviation from even pace |
| VDOT bracket | [1 s, 86 400 s], 100 steps | bisection domain and precision |
| Cameron domain | a(x) > 0 (below about 277 mi) | fitted-curve validity |
† The ±x% gloss is a first-order reading of the log-space half-width
σ. The band is exactly symmetric multiplicatively, not linearly: σ = 0.10 spans
exp(±0.10), which is +10.5% / −9.5%, not a literal ±10%. The
percentages are a convenient linear approximation for small σ.
BThe goal-readiness verdict
A small helper grades a goal against the model's likely projection. Both are first rounded to whole seconds, the precision every surface displays, so the verdict cannot contradict the shown numbers:
likely ≤ goal → achievable goal < likely ≤ goal·1.05 → ambitious (within 5 %) likely > goal·1.05 → stretch
Citing this page
doughworks (2026). The PaceWise race projection model, edition 1. https://pacewise.doughworks.dev/model. The formulas and constants are free to reproduce with a link back; the WMA factor tables carry their own CC BY 4.0 attribution to Alan Jones and the Runalyze project.
The model, running on your results
PaceWise is the free app this maths was built for. Log your races and it projects every distance from all of them, with the band and the stance described above. Offline, no account.