Not a product post. One link at the bottom, ignore it if you like.
I build race-day pacing from GPX files. Every pacing model I know of, mine included, prescribes the fourth climb of the day at the same %FTP as the first. That’s physiologically wrong: achievable power declines with accumulated work, and durability is a performance parameter that FTP measured fresh doesn’t capture (Maunder et al. 2021).
The literature is solid in professionals and thin in amateurs, so I ran it on real rides. Three of the four things I thought I’d found didn’t survive. Two of them were my own analysis fooling me, and one of those traps will catch anyone doing within-ride fatigue work, which is the main reason I’m posting.
Dataset
| Candidate rides (≥3 h, outdoor, power + elevation) | 456 |
|---|---|
| Rides with ≥1 climb ≥5 min with power | 364 |
| Climbs observed | 1,350 |
| Riders | 33 |
| Clean climbs ≥10 min (FTP and weight known) | 749 |
Design
Within-ride comparison: each late climb measured against the first climb ≥10 min of the same ride, which removes rider and day as confounders. 464 pairs. Effort is expressed as %FTP, with effort ratio (mean power against the rider’s own best power at that duration over the preceding 90 days) as a second metric. Both point the same way; %FTP is used in the tables below.
1. Field durability is real, and much smaller than lab durability
| Δ kJ/kg vs first climb | n | Δ %FTP (mean) | median |
|---|---|---|---|
| 0–5 | 57 | +2.6 | 0.0 |
| 5–10 | 104 | −2.6 | −1.9 |
| 10–15 | 103 | −1.7 | −2.6 |
| 15–20 | 66 | −3.5 | −3.7 |
| 20–30 | 87 | −4.4 | −3.5 |
| 30–45 | 40 | −4.7 | −3.2 |
Global slope −0.13 %FTP per kJ/kg (r = −0.13). In effort-ratio terms, −0.27 points per kJ/kg (r = −0.21). This is the one result that survived every correction below.
Lab work with maximal efforts reports 6.5–12.5% decline after ~14 kJ/kg. I see 3–4% after 15–30 kJ/kg. I don’t think the literature is wrong, I think we’re measuring different things. Field efforts are voluntary: the rider is pacing, not testing. What this measures is a floor of capacity, not capacity. For prescribing pacing that’s arguably the more useful quantity, because it’s what people actually sustain and still finish on. It is not comparable to a post-fatigue TT and shouldn’t be quoted as if it were.
Note the plateau: the 20-30 and 30-45 bins are nearly identical. The real shape saturates rather than continuing linearly.
2. My model was three times too steep, and being right on average hid it
Comparing my v1 predictions against observed power relative to each rider’s fresh baseline (<8 kJ/kg), n = 515: mean predicted 0.964 against 0.969 observed, and monotonic across bins. Calibrated on average, and wrong exactly where it changes a prescription. Where the model says 0.91, riders hold 0.94. The slope was about 3x reality and only the clamp was saving it.
If you’re building anything similar, this is the failure mode to check for. Aggregate calibration tells you almost nothing about the tail, and the tail is the only part that alters what you’d tell a rider to do.
3. Prior intensity looked like the best predictor. Then the sign flipped.
This was going to be the headline, because it lines up with Spragg 2024 and the 2025 systematic review: intensity of prior work, not quantity, drives the downward shift. The first pass agreed, and the ranking was clean:
| Prior-work predictor | r |
|---|---|
| raw kJ/kg | −0.13 |
| kJ/kg above FTP | −0.17 |
| IF of prior work | −0.27 |
Then two numbers stopped me.
The baseline climb’s own effort correlates −0.51 with Δ, which is by a distance the strongest single relationship in the dataset. And the baseline climb’s effort correlates +0.79 with prior IF, because the baseline climb is inside the prior-work window. Prior IF and baseline effort are close to the same variable. A rider who buries himself on climb 1 therefore shows a high prior IF and a large subsequent drop, for arithmetic reasons.
So I re-ran it two ways: excluding the baseline climb’s window from prior work, and then partialling out the baseline climb’s own %FTP, which is the direct test against regression to the mean.
| Prior-work predictor | r (baseline climb included) | r (baseline window excluded) | partial r (controlling baseline %FTP) |
|---|---|---|---|
| raw kJ/kg | −0.13 | −0.13 | −0.16 |
| kJ/kg above FTP | −0.17 | −0.15 | +0.06 |
| IF of prior work | −0.27 | −0.18 | +0.23 |
Excluding the baseline window isn’t enough on its own: −0.18 is still steeper than raw kJ/kg, and I’d probably have published that. The test that matters is the last column, and there the sign flips. Holding the baseline climb constant, riders who rode harder between climbs went on to climb the late climb harder, not softer.
That’s a good-day effect, not fatigue. On a day when the legs are there, everything is above par, including the bit in between the climbs.
Only raw kJ/kg is stable across all three specifications. Both intensity measures move around or reverse.
I’m not claiming the literature is wrong. Spragg and others used controlled prior work; I have people riding bikes as they please. The honest conclusion is narrower and, I think, more useful: with voluntary field efforts the effect of prior intensity is not identifiable. The point estimate travels from −0.27 to +0.23 depending on a defensible analytic choice, and the rider’s intention sits on both sides of the regression. Anyone measuring prior intensity from ride files is at real risk of measuring how hard the rider felt like going that day.
I’d like to know whether anyone has a design that gets around this without a lab.
4. Level doesn’t separate riders, and neither can I separate individuals
Pooled slope by level: intermediate −0.15, advanced −0.10, both r ≈ −0.1. In professionals the level effect under fatigue is well established (Muriel 2021, Mateo-March 2022, Gallo 2022). In this amateur sample it isn’t there.
Per-rider slopes (23 riders with ≥8 clean climbs ≥10 min): median −0.25, SD 0.27, IQR −0.39 to −0.12, 5 of 23 positive.
I read that spread as evidence durability is individual and worth modelling per rider. Then I compared it against the noise in estimating it. Median standard error on one rider’s slope is 0.17, and 0.16 for riders with 20–30 climbs. The RMS of those standard errors is 0.32, against an observed between-rider SD of 0.27. Subtracting gives a negative variance estimate, i.e. the implied true between-rider SD is zero.
Simulating riders who share an identical true slope and differ only by sampling noise, using each rider’s real number of climbs:
| IQR | positive slopes | |
|---|---|---|
| simulated, all riders identical (n=20 each) | 0.29 | 14% |
| simulated, all riders identical (n=30 each) | 0.23 | 10% |
| simulated, all identical, each rider’s real n | 0.25 | 13% |
| observed | 0.27 | 22% |
Estimation noise alone reproduces the observed dispersion. One residual worth flagging rather than hiding: the simulation matches the IQR closely but under-predicts positive slopes, 13% against 22%, which is about two riders’ worth of excess. Those are plausibly genuine negative splitters rather than unusually durable riders, but I can’t show that.
So the dataset can’t distinguish “durability varies between riders” from “durability is similar and each rider is measured badly”.
Where that leaves it
One usable result: a small, saturating durability derate, roughly 3–4 %FTP by 20–30 kJ/kg, driven by accumulated work and not by its intensity. That’s what I’ll calibrate against and ship. Everything more ambitious is currently unsupported by field data.
Limitations, stated plainly: voluntary effort means these are floors, not capacities; the baseline climb already carries prior work, so low bins are compressed; the model is linear and the truth saturates; climbs are matched on ≥10 min but not on duration or gradient, and the fourth climb of a route is rarely the same shape as the first; correlations are weak (|r| 0.1–0.3), consistent with field literature (Leo 2022); and regression to the mean via the baseline climb may persist in weaker form anywhere baseline effort correlates with what preceded it.
Two things I’d like from this forum
A design, for 3. How do you measure the effect of prior intensity when the rider chooses both the prior intensity and the effort you’re measuring? Fatigue-conditioned maximal curves (best 20 min after >X kJ, WKO style) measure capacity rather than intention, but need riders who actually go deep late. Is anyone computing these routinely, and is the shape stable across a season? More data won’t fix this one. It’s a design problem.
Data, for 4. Long outdoor rides with power and elevation, several climbs over 10 minutes, and ideally a deep history rather than a handful of rides. Resolving differences of 0.1 %FTP per kJ/kg between riders needs a standard error near 0.05, which at the observed noise level means roughly 300 qualifying climbs per rider. Even a coarse answer needs 70 to 100. That makes per-rider durability modelling from voluntary efforts look like a dead end, and I’d like to be wrong. Enough deep histories would settle it.
What you get back: your own slope, where you sit against these 33, and an honest answer on whether your data is deep enough for the number to mean anything. I’ll post aggregate updates in this thread as the sample grows.
Reply here or DM me.
I build Trainara, a cycling coaching app, which is where these rides come from and where this ends up. If you want to poke at it while you’re here, I have 25 three-month codes for people sending data, valid until 12 October. Entirely optional. I’d rather argue about the method.