CRIS GROSSMANN LET'S BUILD →
The Health Lake · one body, fifteen years

My doctor sees me
once a year.
This sees every night.

Every ride, run, swim, lift and night of sleep since 2012, joined in one database I own — and asked questions no single app can answer, because no single app holds both sides of the join.

3,778Sessions
8,590Nights
75Races
353Week streak
15Years
01 — The decade signal

My heart got seven beats slower while I got nine years older

Resting heart rate, yearly average across 3,345 nights: 54.6 → 46.7. Age says it should drift up. Training said otherwise.

Each point is a year's mean overnight resting HR. No app shows you this — Garmin keeps ~2 years, and your doctor gets one reading, in a chair, while you're stressed about being at the doctor.

02 — The dose-response

Every weekly training hour buys resting heartbeats

Group 3,345 nights by how much I trained the seven days before: the curve is monotonic. Quiet weeks: 50.7 bpm. Twelve-plus-hour weeks: 46.7.

r = −0.25 across nine years. This chart needs the training log joined to the sleep log — Strava has one half, the sleep tracker has the other, neither has both. That join is the entire point of the lake.

03 — The season in your chest

December runs two beats higher than May

Same body, same training habits — a +2 bpm winter tax, every year, like clockwork.

Less daylight, more indoor sessions, holiday food, colder air. Any one year this would be noise. Averaged over nine winters it's a pattern — and a reason not to panic when a December reading looks "high."

04 — The null result

More sleep does not raise my HRV

739 nights of overnight HRV against hours slept: r = 0.02. A flat line — and the error bars say it isn't hiding an effect.

Every wellness app implies more sleep → better recovery scores. For this body, duration doesn't move HRV at all — what moves it is training load and alcohol-free weeks. Generic advice is generic. A personal baseline is the only baseline that means anything.

Why this null is trustworthy: the spread between buckets is 2.1 ms (42.7 at five hours, 44.8 at ten) while the spread within a single bucket is about 5 ms. Every 95% confidence interval overlaps every other one. The four-hour point looks low-ish but carries n=25 and the widest scatter of the set (SD 10.1) — that's noise wearing a trend's clothes.

Publishing the null result on purpose. Data that only ever confirms is data you should distrust.

05 — Fifteen seasons

Where 3,600 hours went

Somewhere in there hides the number I'm proudest of: 353 consecutive weeks with at least one session. No blank week since November 2019 — through lockdowns, a newborn, a company exit.

Hover any year — hours deduped (watch+Edge twin recordings merged). You can read my life in it: the 2020 lockdown bike spike (167 h), the 2022 Ironman-scale year (371 h), the 2025 run pivot that ended in a sub-40 10K (120 h of running, 15 of cycling), and the 2026 triathlon rebuild.

06 — The race ledger

75 start lines since 2012

RUN · 37TRIATHLON · 34BIKE · 4

Latest: two sprint triathlons, seven days apart, August 2026 — top 5% of the field at 45. The gap to the age-group podium closed from 4:34 (2023) to 71 seconds. Every start line, with its percentile, lives in the race ledger. The racing story itself → /race-engineering/

ALL 75 RACES, WITH PERCENTILES
07 — The stack

What I actually take, and when

MORNING · WITH BREAKFAST

  • Creatine monohydrate3–4 g
  • Vitamin D35,000 IU
  • Omega-32 g
  • Zinc bisglycinate25 mg

EVENING · BEFORE 22:00

  • Magnesium glycinate300 mg
  • Omega-32 g
  • CoQ10, with dinner fat200 mg

Boring on purpose. Each item earned its slot from bloodwork or a measured need — vitamin D moved 35→53 ng/mL on this dose — and the stack is closed: nothing gets added without a marker that says so. Timing matters more than brands: magnesium at night, D and zinc with food, CoQ10 with the fattiest meal.