Platform Updated 2026-08-22 View as Markdown

Analytics

Most of the analysis happens before you ask for it. Background workers compute correlations, records, summaries and statistical models on a schedule, and the coach reads the result.

That ordering is deliberate. Deriving statistics inside a conversation means deriving them from whatever slice of data happened to be in context, which produces answers that are confidently wrong — a "personal best" that is only the best of the last thirty days. Computing ahead of time against the full history removes that class of error entirely.

The correlation engine

Runs across every module at once — habits, nutrition, wearables, bloodwork, genetics — on the deterministic tier of the background pipeline, every couple of hours. See when things run.

Known physiology is tested against your data. Rather than asserting that sleep drives recovery, the engine checks whether it does for you, and labels the result confirmed, contradicted, or confounded. A contradiction is often the more useful finding.

Statistical controls are applied. Partial correlation controlling for time trend and sleep, so a relationship that is really just "both improved over six months" does not present as causal. Autocorrelation-adjusted significance, because consecutive days are not independent samples. Multiple-testing correction, because testing forty metrics against each other will produce spurious hits by construction.

Results are stored as a graph. Edges carry the coefficient, the partial coefficient, lag, p-value, sample size, tier and provenance. Depth-2 traversal assembles mechanistic chains — sleep to recovery to next-day strain capacity — instead of asserting them.

Every edge is graded robust, probable, hypothesis or confounded, and that grade is the first thing to read — a coefficient without its tier is not a finding. The verdict on a relationship the engine expected to find is a separate vocabulary from the tier on one it discovered; confidence tier and prior status explain which is which and why filtering the graph for confirmed returns nothing.

Behaviour-to-marker links. Daily behaviours are tested against bloodwork markers over a biologically plausible exposure window, so a marker that responds over eight weeks is not correlated against yesterday's meals.

You can also ask for a pair nobody precomputed. On-demand analysis applies the same guards, and the result is always labelled a hypothesis regardless of how strong the coefficient looks — a single fished pair has no multiple-testing protection.

Precomputed models

The insights engine maintains a set of statistical models, queryable in the app and via get_insights over MCP:

Model What it answers
Readiness score How prepared you are today, as a single score plus the contributors that moved it
Recovery formula Which of your behaviours actually move your recovery, and by how much
Lead-lag relationships Which metric moves first when two move together
Goal ETA Projected arrival with Monte Carlo confidence bands
Streak survival The probability a streak of a given length continues
Training load Accumulated load against capacity
HRV baseline Your personal baseline and deviation from it
Momentum Whether you are building or slipping right now
Dose-response Whether more of a behaviour keeps helping, or plateaus
Changepoints Dates where a metric's regime actually shifted
Behavioural archetypes Recurring patterns in how you operate

Your recovery formula

Worth describing on its own, because it is the model most likely to be quoted back at you and the one with the most ways to be wrong.

It is a regression of today's recovery on last night's sleep and yesterday's behaviour, reported as recovery points per unit — "sleep duration: +6 recovery points per extra hour" — alongside the R² and the number of days it was fitted on. Prior-day strain and sleep duration are always in the model. Exercise, vitamins and eating quality join it conditionally.

Two guards decide what gets stated, and both exist because the model was confidently wrong without them.

A behaviour has to be logged often enough to model. An optional behaviour earns a slot only if it is actually recorded on at least 30% of the days being modelled. The reason: a habit you log a seventh of the time, with every unlogged day treated as "didn't do it", produces a coefficient that measures whether you were engaged enough to fill in the row rather than whether the habit did anything. That is not a subtle bias — it is how "prior-day vitamins: −9.9 recovery points" reached the coach as a finding. Below the floor the term is dropped rather than hedged, because there is nothing there to hedge.

A term the correlation engine calls confounded is labelled as such. Each surviving term is matched back to its edge in the correlation graph, and a confounded edge makes the coefficient read [confounded — not a direct effect] wherever the formula is stated. The coefficient is real and stays in the model; what it is not is a lever you can pull. A term the engine has no edge for is left plain rather than guessed at — the label is only ever added, never inferred.

R² is in-sample fit. It describes how well the model explains the history it was built from, which is not the same as how well it predicts tomorrow.

Facts and records

An all-time fact index per metric: first and last recorded day, minimum, maximum, lifetime total where a total is meaningful, current and best streak, and 30- and 90-day rolling averages.

Coverage is derived from the metric registry rather than hand-maintained, which is what stops it from silently omitting a group of metrics — an earlier hand-written version omitted every WHOOP column, and the coach reported bests that were nowhere near the true maxima.

Direction is declared per metric, because it is not inferable. Lower is better for resting heart rate and mile time. Higher is better for HRV. Weight is deliberately neither, because whether up or down is better depends on your goal, not on the metric.

Summaries

Narrative rollups written by the summarization pipeline: weekly, monthly, quarterly and yearly reviews, lab and methylation interpretations, mission analysis, personal records, and a cross-module correlation narrative.

These are embedded alongside individual days, so a question about a period retrieves the period rather than reassembling it from ninety rows.

Charts

Trends, distributions and comparisons over any tracked metric, rendered in the app. Bloodwork markers get sparklines against their reference ranges.

When things run

The pipeline is split in two by cost, which is the thing to understand if you are reasoning about how fresh a number is.

Worker Schedule Does
Derived tier Every 2 hours Correlations, the insights models, personal records, period summaries, the all-time fact index, labs, methylation and supplement pipelines
Generative tier 01:00, 05:00, 10:00, 14:00, 17:00, 21:00 UTC The steps that call a reasoning model: meal enrichment, the narrative journey, mission analysis, and the belief check against your learnings
WHOOP sync Hourly, per your own clock Pulls at 05:00–09:00 then every two hours to 23:00, in your timezone
Embeddings 06:00 UTC Batch-embeds anything flagged during the day
Learning maintenance 04:00 UTC Decay, expiry, consolidation

Why the split. Correlations and insights are seconds of arithmetic; mission analysis alone is allowed ten minutes of reasoning-model time. Running them in one loop meant the cheap work inherited the expensive cadence — a correlation refreshed only as often as the prose did — and one slow account could exhaust the budget before the rest of the queue was reached. Separating them lets the arithmetic run several times a day.

WHOOP sync is on your clock, not UTC. The cron fires hourly and each account is pulled when its own local time reaches one of the scheduled hours, so everyone gets the same schedule in their own day wherever they live. It is hourly through the morning because that is when WHOOP scores the night's sleep and the day's recovery, then every two hours to follow strain as it accumulates. The overnight stretch is skipped: nothing new is scored while you are asleep.

Days are also embedded inline as you save them; the cron pass is a fallback for anything that failed or was written while the embedding service was unavailable.

Data quality

Analysis is only run on values that can carry it. WHOOP recovery from the calibration period and sleep stages from a night with a significant sensor gap are suppressed for analysis while remaining visible in the ledger exactly as reported. See quality gating.