← ontrack lab

Metres per beat: the number that caught my overtraining

How far you run per heartbeat, adjusted for the hills, is a decent gauge of aerobic fitness. I computed it from a decade of my own Garmin files. It climbed for months into the London Marathon, then fell for five weeks afterwards while I kept training. That fall was overtraining, and it was in the data before I felt it in my legs.

Oliver FoxOliver FoxFounder of ontrack · doctor & researcher · runner

12 July 2026 · 9 min read

Overtraining is usually diagnosed in hindsight: a couple of bad weeks, a flat race, and then the realisation that you should have eased off a month ago. I wanted to know whether it shows up in training data before you can feel it. In my case it did, in a number you can compute from any run that has heart rate on it.

The number is how far you travel per heartbeat, adjusted for hills. If you cover more ground for each beat, your engine is more economical, and tracked over months that makes a usable fitness gauge. The files a watch records contain everything you need to compute it, so I built it from a decade of my own Garmin data.

What the number measures

For each second of a run I take the distance covered, price it for gradient with the Minetti cost-of-running curve, so that a metre uphill counts for more than a metre on the flat, and divide by the heartbeats that second cost. That gives grade-adjusted metres per beat.

To make one run comparable with another I apply two filters. Efficiency at threshold and efficiency on an easy jog are different quantities, so I keep only steady, near-level seconds with heart rate between roughly 120 and 160. And a single GPS glitch or dropped heartbeat can drag a mean around, so each run contributes the median over 30-second windows instead.

Smoothing the per-run values over 21 days turns them into one number a day, and that's the line below: a slow-moving estimate of aerobic fitness.

Loading the fitness trace…

The first question is whether this is signal or noise, and over four and a half years I think it's clearly signal. The build phases are distinct, both enforced breaks are visible, and the climb through 2026 is long and steady. There's day-to-day wobble, but it's small compared to the multi-month swings.

Can it tell me what training worked?

The first thing I actually wanted from this data was an answer to which sessions make me faster. I modelled each month's change in fitness against the training that came before it, holding starting fitness constant, and the result was inconclusive: volume and long runs lean the right way, but nothing reaches statistical significance for a single runner.

There are two reasons, and anyone trying this on their own data will probably hit both. My training is very polarised, four easy runs in five and almost no intervals, so there's little variety for a model to learn from. And the largest pattern in the data isn't a training effect at all, it's regression to the mean: fitness rebounds after a bad patch and sags after a peak, and if you don't control for that you'll credit whatever training happened to be nearby.

So the number couldn't tell me what to do. It was much better at telling me what was happening, and the marathon is the clearest example.

The London Marathon

The thing to look at in this window isn't the absolute level; the number was higher back in 2022. It's the trend. Through the first months of 2026 the line climbs steadily and keeps climbing to the end of April, peaking as I taper. I ran London in 2:23:39 at the top of that rise. The metric is computed the same way for every run, so the rise into race day isn't a story fitted afterwards; it's where the line was already going.

Loading the marathon zoom…

I didn't stop training after the race, but the number stopped climbing and fell about 3% over the next five weeks.

The symptoms arrived over the same stretch: bad sleep, heavy flat legs, easy runs that felt harder than their pace justified, and muscles twitching at rest (fasciculations). The number and the way I felt were describing the same thing.

What a 3% drop actually costs

Three per cent sounds like a rounding error, so it helps to convert it into pace. Metres per beat is speed divided by heart rate, so speed is metres per beat times heart rate: if the number falls 3% and my heart rate stays the same, I'm running 3% slower.

In the band where it's measured, that took my easy flat running at 140 bpm from about 3:56/km to 4:04/km. Eight seconds a kilometre at the same effort, which is the thing I'd been noticing on easy runs without being able to name it.

At race pace the numbers get harder to ignore. London was 2:23:39, an average of 3:24/km. Take 3% off that pace and the clock reads about 2:28:15, four and a half minutes slower on the course I'd just run. Or keep the pace and pay with the heart instead: holding 3:24/km at end-of-May fitness would have cost roughly five extra beats a minute for two and a half hours. One caveat: the number is measured well below race effort, so carrying it to marathon pace assumes the loss scales, which is roughly but not exactly true.

There's also a way to see the cost without extrapolating at all. The line reached 1.76 on the way down at the end of May, and the last time it had passed 1.76 on the way up was 10 February. Five weeks of training through fatigue had undone ten weeks of building.

Why it fell

The most likely explanation is the simplest: I hadn't recovered. A hard marathon leaves weeks of muscle damage and nervous-system fatigue, and one of its clearest signatures is a heart rate that sits high for any given pace. Because the metric is distance per beat, a raised heart rate at the same speed reads immediately as fewer metres per beat, even if underlying fitness hasn't really changed. Training normally on top of that state is pretty much the definition of overreaching.

Two caveats. The number can't separate a genuine loss of fitness from a temporary rise in the cost of running; here both point the same way, and for a warning light the difference doesn't matter much. The second is weather: the decline runs into a warming May and June, and heat alone raises heart rate at a given pace, so some of the drop is season rather than fatigue. I don't think heat is most of it, though, because the fall starts the day after the race rather than with the first hot week, and heat doesn't explain the sleep or the legs.

Every heart rate at once

The 3% was measured at one heart rate. The same computation works at every heart rate I run at, each traced from its own runs rather than scaled from a single curve, one line per beat per minute.

The fan only covers 118 to 157 bpm. Pooled across four years there's plenty of data outside that range, but a trace needs feeding every few days to stay meaningful, and I don't visit 105 or 170 bpm often enough. Those lines go weeks between updates and lurch when one finally arrives, so I cut them.

Loading the heart-rate fan…

I expected a tidy fan, the same shape stacked at different heights, on the logic that faster running is just higher heart rate. That isn't what came out. The bands drift apart, and around the marathon they disagree with each other. The post-London fall is barely visible at 118 bpm, about 2%, which on an easy jog you'd never feel. At 128 it's 3%, at 133 it's 4%, and it peaks above 7% around 143 before easing off near the top of the range.

The damage was concentrated in the middle of the range: the steady, moderately hard aerobic running that fills a marathon block. My easy jogging was more or less fine, which I suspect is why nothing felt obviously wrong. The runs where the cost had really climbed were the ones I did least often, and each one on its own was easy to blame on a bad night's sleep.

Why it can't tell you your race time

An obvious use for the fan is prediction: pick your race heart rate, read off the pace, multiply up. I tried it against all fifteen races in the trace and it fails, sometimes by a lot. It predicts 3:36/km for London, where I ran 3:24. For a 10,000m on the track it predicts 3:17/km against an actual 2:49, and for a muddy Surrey League cross country it predicts 4:21/km when the truth was 5:56. The errors run from 27% too slow to 22% too fast.

Three different things break it. Heart rate has a ceiling, mine is 184, so once a race is hard the legs keep accelerating while the heart can't, and metres per beat climbs far above anything the aerobic band predicts. The gradient correction prices hills but knows nothing about surface, so deep mud reads as a catastrophic loss of fitness rather than a slow field. And race day itself adds something: at London I averaged 2.02 metres per beat against a training-band value of 1.81, roughly 10%, from the taper, the flat closed roads, the shoes and a cool morning.

The scope of the metric is narrower than "how fast can I race": it describes steady aerobic running at a given heart rate, and nothing above that or off road. Within that scope it behaves well.

What this means for you

The part that transfers to other runners isn't session selection, which was inconclusive, and isn't race prediction, which failed outright. It's monitoring. In a hard block every runner ends up asking the same question: is this training being absorbed, or am I digging a hole? While efficiency keeps climbing, it's the first. When it flattens or falls while the training is still heavy, it's the second, and the useful response is an easier week or two rather than more pushing.

ONTRACK computes grade-adjusted metres per beat from your uploaded runs. If a block has started to feel like a slog that isn't paying off, look at the trend before you write the feeling off. In my case the falling line was visible weeks before I eased off, and acting on it would have saved me most of those five weeks.

How it’s made — the technical bit

From watch to trace

The raw data is a decade of Garmin .FIT files, a little over a thousand runs once the wellness snapshots are dropped. A Python script reads every one-second sample: pace, heart rate, and barometric altitude. Gradient comes from smoothed altitude over the ground travelled, clamped to a sane range, and the Minetti (2002) polynomial converts it into a metabolic cost, so a metre uphill counts for more than a metre on the flat.

Per run I keep only the aerobic band (moving, near-level, heart rate roughly 120–160) and take the median grade-adjusted metres per beat over 30-second windows, which shrugs off the occasional GPS or strap artefact.

The fitness line is an evidence-weighted 21-day exponential moving average of those per-run values. Each run moves the estimate in proportion to how much steady aerobic data it carries, so a short or scrappy run barely shifts it while a long even one moves it more. Rest days hold the last value, so a gap never drags the line down, and the next real run pulls it back to the current reading. Race dates come from my own results.

About the gaps

This is the weakest part of the method. When there's no run — a rest day, an injury, a week where the watch died, or a run with no usable steady aerobic seconds — the line holds its last value and carries on. Nothing is interpolated, no uncertainty is tracked, and the trace looks exactly as confident either side of a two-month lay-off as it does mid-block.

A better construction exists: a state-space model, with a latent fitness that drifts while unobserved and is measured noisily whenever a run happens, so that uncertainty widens across every gap and tightens again when data returns. That's essentially a Kalman filter, and the line would carry a confidence band that visibly fattens over the breaks. The heart-rate fan needs it even more, since the thin bands at the edges of the range currently get a dashed stroke and a written warning where they should get error bars. I haven't built that version yet, so where the line crosses a long break, read it as an assumption rather than a measurement.