Methodology
Every number, explained.
Keely publishes how it computes every number. Recovery, Load, Stress and Sleep are built from the signals your Polar Loop records, heart rate, beat-to-beat intervals, movement and skin temperature, with the formulas and constants on this page. Everything is computed on your iPhone.
Updated
- Recovery
- 0–100 %, last night against your 30-night normal
- Load
- Minutes weighted by heart-rate zone, no ceiling
- Stress
- 0–100, heart rate and HRV against your calm, only while still
- Sleep
- Stages from the Loop, measured against your need
- Computed
- On your iPhone; raw heart data never leaves it
- Updated
- When a formula changes, this page changes with it
Principles
- Signals in, numbers out. The band delivers signals. Every score is Keely’s own calculation, so the same formulas would work with another band.
- Never fabricate. Missing data is shown as missing, older readings show their time, and nothing estimated is shown as a measurement.
- Every number is explainable. Each score keeps its inputs, and the app shows what moved it.
- Deterministic. The same data always gives the same numbers. The calculations are pure functions, tested against hand-checkable examples like the ones on these pages.
What the Loop records
- Heart rate, around the clock: an average every 5 minutes at rest, and every second during activity.
- Beat-to-beat intervals (peak-to-peak intervals from the optical sensor), the raw material for HRV, breathing rate and stress.
- Movement: steps and an activity level for each minute.
- Skin temperature, and its nightly difference from your normal.
- Sleep stages from the Loop’s own staging.
- Live heart rate and beat intervals while Keely is open and the band is connected.
Stored data syncs from the band to your iPhone. Band data is deleted only after Keely has saved it.
Cleaning the beats
Optical sensors see noise: a moved wrist, a loose band. Before any HRV, breathing or stress calculation, each beat interval passes two filters:
- Beats the band flags, beats with an error estimate above 30 ms, and intervals outside 300–2000 ms (30–200 beats a minute) are dropped.
- Intervals more than 25 % from the median of their 11 surviving neighbours are dropped.
Differences are only taken between beats that were next to each other, so a dropped beat never creates a false jump.
HRV
HRV is RMSSD, the root mean square of successive differences between clean beat intervals, in milliseconds:
RMSSD = √( average of (interval[i+1] − interval[i])² )
For example, intervals of 1000, 1010, 990 and 1005 ms give differences of 10, −20 and 15, so RMSSD = √((100 + 400 + 225) ÷ 3) ≈ 15.5 ms. Nightly HRV uses deep (slow-wave) sleep and needs at least 30 differences; with too few, it uses the whole night.
Resting heart rate
The lowest 10-minute average heart rate overnight, from windows with at least 5 minutes of samples.
Breathing rate
Heart rate rises a little with each breath in and falls with each breath out, so the beat intervals oscillate at your breathing rate. Keely finds that rhythm in 2-minute windows while you sleep: clean beats resampled at 4 Hz, the trend removed, and the power spectrum searched between 0.15 and 0.40 Hz (9–24 breaths a minute). A window counts when its peak is at least 3 times the band’s average power, and the night’s rate is the median of at least 3 such windows. A peak at 0.25 Hz is 15 breaths a minute.
Your normal
- For each nightly signal (HRV, resting heart rate, breathing rate and skin temperature), your baseline is an exponentially weighted average of the last 30 nights, with a half-life of 7 nights, so last week counts half as much as last night.
- The standard deviation comes from the same window, and your normal range is the baseline ± one standard deviation.
- The first Recovery needs 3 nights of HRV and resting heart rate, and baselines are fully personal after 14. A night never counts toward its own baseline.
Recovery
| Input | Weight | Better when |
|---|---|---|
| HRV (RMSSD in deep sleep) | 45 % | Higher |
| Resting heart rate | 25 % | Lower |
| Sleep (asleep ÷ need) | 20 % | Closer to 100 % |
| Breathing rate | 5 % | At your normal |
| Skin temperature | 5 % | At your normal |
z = (value − baseline) ÷ SD
z sleep = (asleep ÷ need − 1) ÷ 0.15
c = Σ weight × z
Recovery = 100 ÷ (1 + e^(−1.6 × c))
Signals where lower is better flip sign, so a positive z always helps. Breathing rate and skin temperature count only against you, sleep counts at most +1, and every z is capped at ±2.5. Standard deviations have floors: 5 % of the mean for HRV, 1 bpm, 0.3 breaths a minute and 0.2 °C. The states are Primed (67–100), Balanced (34–66) and Restore (0–33). How Recovery works, with a worked example.
Load and heart-rate zones
HRR = (HR − resting HR) ÷ (max HR − resting HR)
points = 10 × (HRR − 0.45) a minute, from 0 to 5.5
Load = the day’s points since local midnight
| Zone | Share of heart-rate reserve |
|---|---|
| Z1 Recovery | 50–60 % |
| Z2 Endurance | 60–70 % |
| Z3 Tempo | 70–80 % |
| Z4 Threshold | 80–90 % |
| Z5 VO₂ max | 90–100 % |
Resting heart rate for zones is the average of your last 7 nights. Maximum heart rate is the highest seen in a workout (the highest median over 5-second windows, from every-second samples), or 208 − 0.7 × age before your first workout.
chronic = 28-day average daily Load
target = chronic × (0.2 + 0.014 × Recovery) ± 15 %
Balance = 7-day average ÷ 28-day average
Chronic Load starts at 110 until you have 14 days. Balance reads Detraining below 0.8, Maintaining to 1.0, Building to 1.3, Overreaching to 1.5, and Overload above. How Load works, with its examples.
Workouts
A workout is at least 10 minutes at or above the Zone 1 floor, found in 1-minute medians of the Loop’s heart rate, with dips of up to 2 minutes allowed. It’s classed by the share of its minutes in each zone, checked in order: VO₂ max (Zone 5 ≥ 15 %), Threshold (Zones 4–5 ≥ 35 %), Tempo (Zone 3 ≥ 40 %), Recovery (Zone 1 ≥ 60 %), Endurance (Zones 1–2 ≥ 60 %), otherwise Mixed.
recovery time = 10 + 0.12 × Load × (1.35 − Recovery ÷ 100) hours
The 1-minute heart-rate recovery is the steepest 60-second fall starting in the workout’s last 3 minutes, from every-second samples only; without them it isn’t shown.
Stress
zHR = (HR − (resting HR + 12)) ÷ 8
zRMSSD = (ln RMSSD − (ln nightly HRV − 0.25)) ÷ 0.35
s = 0.9 × zHR − 0.9 × zRMSSD
Stress = 100 ÷ (1 + e^−(s − 1.4))
Without RMSSD, s = 1.2 × zHR. The levels are Calm (0–25), Mild (26–50), Elevated (51–75) and High (76–100). Stress is scored per 5-minute window, from at least 20 clean beat pairs, and only while still: a window is Active, never scored, when any minute has more than 10 steps or more than light activity, when it overlaps a workout, or when heart rate is at or above the Zone 1 floor. After activity, windows wait while heart rate is more than 15 bpm above resting, for up to 30 minutes after a workout and 10 minutes after a walk. How Stress works.
Sleep
debt = min(60, 0.25 × shortfall over 3 nights)
strain = min(30, 40 × max(0, Load ÷ target top − 1))
need = goal + debt + strain
performance = asleep ÷ need
consistency = 100 − 0.45 × average deviation
lights out = usual wake − need − 12
Times are in minutes. The strain part uses yesterday’s Load against the top of yesterday’s target. The deviation is |bed − usual bed| + |wake − usual wake| over the last 14 nights, with “usual” the median.
Stages come from the Loop: Awake, REM, Light (NREM 1–2) and Deep (NREM 3). How Sleep works.
Constants and changes
Some constants are starting values, and they’ll be tuned on real nights from the Loop as they accumulate: the Recovery curve’s steepness (1.6), the sleep scale (0.15), the stress model’s offsets and scales, the sleep-debt and strain shares, the recovery-time formula, and Load’s starting chronic value (110).
When a formula or constant changes, this page changes with it, and so does the app’s explanation. Your stored days are recomputed from the raw samples on your iPhone, so old and new numbers stay comparable.