Skip to content

Fitness Model (CTL/ATL/TSB)

FitRepo implements the classic PMC (Performance Management Chart) model originally described by Dr Andrew Coggan. It uses Training Stress Score (TSS) from each activity to compute three daily metrics.

CTL represents your long-term fitness. It is an exponentially weighted moving average (EWMA) of daily TSS with a 42-day time constant.

CTL_today = CTL_yesterday × e^(-1/42) + TSS_today × (1 - e^(-1/42))

CTL rises slowly with consistent training and falls slowly during rest. A higher CTL generally means greater fitness.

ATL represents your short-term fatigue. It uses the same formula with a 7-day time constant.

ATL_today = ATL_yesterday × e^(-1/7) + TSS_today × (1 - e^(-1/7))

ATL responds quickly — a hard week spikes ATL; a rest day drops it noticeably.

TSB (also called “form”) is simply:

TSB = CTL - ATL
TSB rangeInterpretation
> +25Very fresh — possibly detrained
+5 to +25Fresh and ready to race
-10 to +5Neutral — good for quality training
-25 to -10Some fatigue — training adaptation zone
< -25High fatigue — risk of overtraining

TSS requires a power meter and an FTP value:

TSS = (duration_s × NP × IF) / (FTP × 3600) × 100

Where:

  • NP = Normalised Power
  • IF = Intensity Factor = NP ÷ FTP
  • FTP = Functional Threshold Power at the time of the activity

Activities without power data (e.g. running without a stryd, cycling without a power meter) are excluded from CTL/ATL/TSB.

When querying the fitness timeline via the API or MCP, FitRepo automatically loads 90 days of history before your requested start date to warm up the EWMA accumulators. This ensures CTL and ATL are accurate at the start of your window, not artificially low.

FTP is tracked historically in the user_thresholds table. When calculating TSS for past activities, FitRepo uses the FTP that was in effect at the time of that activity — not the current FTP. This means your historical TSS values are stable even as your FTP changes.

See Thresholds for how FTP history is stored and auto-detected.

  • No heart-rate TSS — FitRepo currently only computes TSS from power. HRrTSS (HR-based TSS) is not yet supported.
  • Cycling only — TSS is only calculated for activities with power data. Running, swimming, and other sports contribute 0 to CTL/ATL.
  • Day resolution — The model is computed at daily granularity. Multiple activities on the same day have their TSS summed.