# How Training Load Works

Canonical HTML: https://effortsignal.com/learn/training-load/

Last content update: 2026-09-16

Published: 2026-09-11

Author: [EffortSignal Editorial Team](https://effortsignal.com/editorial-standards/)

Follow the exact path from recorded heart rate to daily TRIMP, ATL, CTL and TSB.

## One daily heart-rate load series

Completed activity [TRIMP](/learn/trimp/) feeds the fitness/fatigue history. [PSS](/learn/pss/) remains a separate power-load metric: there is no PSS fallback and no user switch that makes this CTL/ATL series power-based.

For local calendar day d, let L[d] be the sum of available TRIMP from activities starting on that day. The implementation uses:

```text
ATL[d] = ATL[d−1] + (L[d] − ATL[d−1]) / 7
CTL[d] = CTL[d−1] + (L[d] − CTL[d−1]) / 42
TSB[d] = CTL[d−1] − ATL[d−1]
```

[ATL](/learn/atl/) means Acute Training Load, [CTL](/learn/ctl/) Chronic Training Load, and [TSB](/learn/tsb/) Training Stress Balance. The smoothing coefficients are exactly 1/7 and 1/42, not 1 − exp(−1/N). TSB describes the balance entering the labeled day, before that day's load.

## Day boundaries, initialization and gaps

The account timezone determines an activity's local start date; an activity crossing midnight is assigned as a whole to its start day. Multiple sessions are summed. Calendar dates, including daylight-saving transitions, advance the daily recurrence once; it is not a rolling 24-hour series. The complete rebuild starts at the earliest recorded activity with ATL and CTL equal to zero. The first 41 days carry low-confidence context. A chart-range change does not reset this state.

A real rest day uses L = 0 and both averages decay. An imported activity without valid TRIMP is marked incomplete. Available TRIMP from other sessions still contributes, possibly leaving a daily numerical zero with an incomplete-data flag. The application cannot identify an activity that was never imported; a missing import can therefore look like no recorded work.

## Verified example

Starting at zero, a first day with 70 TRIMP gives ATL = 10, CTL = 1.666667 and TSB = 0. A following rest day gives ATL = 8.571429, CTL = 1.626984 and TSB = −8.333333. Two same-day sessions of 30 and 40 TRIMP give the same first-day load as one 70-TRIMP session.

## Recalculation and interpretation

Importing older activities, fixing source data, changing applicable thresholds or changing timezone can change historical inputs and later daily values. Recalculation is versioned and uses the applicable persisted state or rebuilds from the natural beginning when a compatible seed is missing. A partial history understates the model even if its arithmetic is correct.

<!-- Readiness shares this series now; its previous-day timing and coverage gate still matter. -->
This model describes accumulated recorded load, not a direct measurement of fitness, fatigue, injury probability or medical readiness. [Readiness workload](/learn/readiness/#workload) uses this same TRIMP ATL/CTL series at the end of the previous local day, with a separate 42-day coverage requirement and component score mapping. Open [Training Load in the app](/features/training-load/) to inspect the history.

## Sources and implementation scope

[Morton, Fitz-Clarke and Banister (1990), impulse-response performance modeling](https://pubmed.ncbi.nlm.nih.gov/2246166/) explains the research background. The formulas, windows, quality gates and examples above describe EffortSignal 0.1.13, checked September 10, 2026. Thresholds and rounding are EffortSignal rules.
