← All metrics

Fitness & fatigue

CTL/ATL/TSB, ACWR, and 80/20 polarization — the Banister/Coggan load model your plan adjusts from.

Illustrative fitness (CTL) climb over a training block Illustrative example — not a real athlete
Illustrative fitness (CTL) climb over a training block
Wk 1Wk 2Wk 3Wk 4Wk 5

CTL (TSS/day average)

Fitness, fatigue & form (CTL / ATL / TSB)

Your fitness (CTL) is a slow-moving average of how much training stress you’ve absorbed; your fatigue (ATL) is a fast-moving average of the same; your form (TSB) is the gap between the two. A positive TSB means you’re fresher than your recent training load; a negative one means fatigue is stacking up.

Worked example Verified real-world example
  1. A pro cyclist starts a 3-week Grand Tour around CTL ≈ 150 — fitness built over months of training.
  2. Racing roughly 150–250 TSS a day for 21 days, the 42-day EWMA (ctl = ctl + (tss − ctl) / 42, applied once per day) keeps pulling CTL upward faster than it decays.
  3. By the final stage, Friel’s own published power-file breakdowns show CTL has climbed to roughly 200.

This is why a 3-week stage race is a fitness-BUILDING event even though it’s brutally hard — daily load outweighs the 42-day decay.

Source: Joe Friel’s published Tour de France power-file analysis

Formula, provenance & citation
Formula
tsb = ctl − atl (before today’s update); ctl = ctl + (tss − ctl) / 42; atl = atl + (tss − atl) / 7
Inputs
Daily total TSS (real, or the hrTSS fallback when no power/pace TSS exists), one point per calendar day, gaps counted as TSS = 0.
Provenance
computed
Unit
TSS (dimensionless, TSS-per-day average)
Method
Banister impulse-response model, EWMA convention (Coggan/Allen)
Citation
Banister E.W. (1991), Physiological Testing of Elite Athletes; Allen H., Coggan A., McGregor S. — Training and Racing with a Power Meter, 2nd ed. (2010), ch. 6.
Licensing note
"CTL"/"ATL"/"TSB"/"TSS" are the vocabulary TrainingPeaks (Peaksware) uses for this same Coggan/Allen model — the formula itself is public domain, only the abbreviations trace to a commercial product.
Implementation pointer
api/backend/backend/pipeline/metrics/fitness.py:174 (fitness_series), fitness.py:579 (_fitness_snapshot). Tests: api/backend/tests/pipeline/test_metrics.py.

Acute:Chronic Workload Ratio (ACWR)

A load-spike heuristic: how this week’s training compares to what your body has adapted to over the last month. A ratio well above 1 means volume ramped up faster than your body had time to adjust.

Worked example Illustrative example — not a real athlete
  1. Acute load (trailing 7 days): 490 TSS.
  2. Chronic load (trailing 28 days, expressed as a weekly average): 350 TSS/week.
  3. ratio = 490 / 350 = 1.4

A 1.4 ACWR lands in the “caution” band (above the commonly cited 1.3 cutoff) — worth easing off before ramping further.

Formula, provenance & citation
Formula
acute = sum(daily TSS, trailing 7 days); chronic = sum(daily TSS, trailing 28 days) / 4; ratio = acute / chronic
Inputs
Daily TSS series (same as CTL/ATL); acute_days=7, chronic_days=28, band cutoffs 0.8/1.3/1.5 (config).
Provenance
computed
Unit
ratio (dimensionless)
Method
Acute:chronic workload ratio (Gabbett)
Citation
Gabbett T.J. (2016) — The training-injury prevention paradox, British Journal of Sports Medicine 50(5):273-280.
Licensing note
No trademarked vendor term — a published sports-science heuristic; MyThreshold’s band labels are its own convention over the commonly cited cutoffs.
Implementation pointer
api/backend/backend/pipeline/metrics/fitness.py:238 (acwr). Tests: api/backend/tests/pipeline/test_metrics.py.

80/20 polarization

How your training intensity splits between easy and hard efforts, two ways: by number of sessions and by actual time spent in each heart-rate zone. Polarized-training research targets roughly 80% easy, 20% hard.

Worked example Illustrative example — not a real athlete
  1. 20 sessions over 28 days: 16 easy, 4 hard (LT/VO2) by session count = 80% easy.
  2. Time-in-zone over the same window: 900 of 1,125 total minutes in Z1/Z2 = 80.0% easy.

Both views agree at 80/20 — a textbook polarized month by Seiler’s model.

Formula, provenance & citation
Formula
easy_pct (by session) = 100 × easy_sessions / total_sessions; easy_pct (by time) = 100 × easy_seconds / total_seconds, where easy = zone ≤ 2
Inputs
In-window workouts, HR-zone time; window_days=28, easy_zone_max=2, target_easy_pct=80 (config).
Provenance
computed
Unit
%
Method
Polarized training (Seiler 80/20 model)
Citation
Seiler S. (2010) — International Journal of Sports Physiology and Performance 5(3):276-291.
Licensing note
No trademarked vendor term.
Implementation pointer
api/backend/backend/pipeline/metrics/fitness.py:331 (polarization). Tests: api/backend/tests/pipeline/test_metrics.py.
← Back to mythreshold.ai