August 29, 2026 · 15 min read · Sugam Budhraja

How Much Health Data Fits in an LLM Context Window? One Night of Heart Rate Costs 32,000 Tokens

Measured with a real tokenizer against a real schema: 288 heart rate samples cost 32,256 tokens, the same night summarised costs 81. The counterintuitive part is the accuracy. On a 110-task health time series benchmark, 16 models given a code interpreter scored 0.69 at best against a naive baseline of 0.61, while purpose-built models reached 0.84 on the comparable subset.

The instinct is reasonable. You have a model that reads 200,000 tokens, a user with a year of health data, and the obvious move is to hand over everything and let the model find what matters.

The arithmetic kills that plan before it starts. The research does something more interesting: it says the cases that do fit get worse as you add data to them.

Both are measurable, so this post measures them rather than asserting them.


The arithmetic, measured

Start from a real record and a real tokenizer rather than an estimate. A Sahha data log sample carries an id, a parent id, a value, a unit, a source, a recording method, a device type, start and end timestamps, and a properties object [1]. One heart rate sample, serialised compactly, is 304 characters and 112 tokens under o200k_base.

That ratio, 2.71 characters per token, is the first thing worth noticing. English prose runs near four. UUIDs and ISO 8601 timestamps fragment badly, so health data logs cost roughly 45% more tokens per character than text does.

Now the only sampling assumption this argument actually needs. A watch recording heart rate once every five minutes produces 288 samples a night:

One night of heart rateTokens
288 raw samples at source resolution32,256
The same night as one summary record81

That is a factor of 398, for one signal, for one night, and it rests on a single well-understood sampling rate rather than a modelled user.

Extend it to a whole user and the range depends on assumptions, so here are two, one deliberately conservative:

Thirty days, one userTokens
Raw, at a conservative 300 samples/day1,008,000
Raw, at roughly 1,100 samples/day (phone, watch, daily workouts)3,722,880
As 100 daily biomarkers [2]132,000
As 5 daily scores with factors~19,000

The conservative row is the important one. Even if you think the 1,100 figure is inflated, and it is a scenario rather than a measurement, a month at 300 samples a day is still a million tokens, which is five times a 200,000 token window. The conclusion does not depend on the optimistic case.

None of this is the interesting part. Everything above is a capacity argument, and capacity arguments expire. Context windows grow and prices fall every year. If tokens were the only issue, the right response would be to wait. The reason to compress is that the uncompressed version answers worse, and that does not improve with a bigger window.

Even with a code interpreter, the models barely beat a naive baseline

HEARTS is a benchmark for LLM reasoning over health time series from UCLA and Google Research, authored by Sirui Li, Shuhan Xiao, Mihir Joshi, Ahmed Metwally, Daniel McDuff, Wei Wang and Yuzhe Yang. It assembles 16 real-world datasets across 12 health domains and 20 signal modalities into 110 tasks, and evaluates 16 state-of-the-art models over more than 20,000 test samples [3].

One methodological detail has to come first, because it changes what the results mean.

The models were not asked to read raw series out of a prompt. HEARTS standardises on the CodeAct framework, which the authors chose specifically “to address context-window limits when working with long time-series inputs.” CodeAct “allows an LLM to reason by writing Python code that reads and analyzes data from files, so the model does not need to ingest the full raw sequence in its prompt” [3]. In other words, every model in this benchmark already had the tool-based architecture recommended at the end of this post. The scores below are what that architecture achieves, not what naive prompt-stuffing achieves.

With that established, here is what 16 frontier models managed:

Reference pointOverall score
Best model evaluated (Gemini 3.1 Pro)0.69
Naive baseline0.61
Worst model evaluated (Nemotron Nano 12B V2)0.47
Specialized models, 32-task subset0.74

The paper states the conclusion in its own section heading: “LLMs make only small gains over a naive baseline, and performance is weakly related to general intelligence indexes” [3]. Some models scored below the naive baseline outright, and Figure 3 excludes them as outliers.

On the curated subset where a like-for-like comparison against purpose-built models is possible, the gap is wider than the table above suggests. Averaged across tasks, specialized ML models reach 0.84, the best LLM result reaches 0.54, and the average across LLMs is 0.46 [3].

The paper’s first stated finding is blunt: “LLMs lag substantially behind specialized models, and the performance on health time series is only weakly related to their general reasoning capabilities.” Its second: “LLMs rely heavily on low-complexity heuristics and explicit priors, and show limited deep temporal reasoning across task categories” [3].

A note on the metric. These are composite scores, not accuracies. Each task is scored with whatever suits its output type, accuracy for classification, intersection over union for localisation, or a normalised sMAPE-derived score bounded to [0,1], and the overall figure is a macro-average across the four categories. That is why the naive baseline comparison is the load-bearing one: it is computed on the same tasks with the same metrics.


The context window problem, in the authors’ own words

The token arithmetic above is not a Sahha observation. The HEARTS authors hit the same wall and had to design around it.

From Appendix C.7, explaining why CodeAct was necessary in the first place:

Direct pure-text ingestion of health time series is fundamentally constrained by LLM context windows, which would render 40% to 60% of HeaRTS tasks unmeasurable due to massive sequence lengths.

Between 40 and 60 percent of a health time-series benchmark cannot be run at all if you put the data in the prompt. That is an independent confirmation of the arithmetic at the top of this post, produced by people trying to build an evaluation rather than sell a data layer.

The authors also checked that CodeAct was not simply measuring Python proficiency. On a 20-task subset short enough for direct ingestion, direct in-context reasoning and CodeAct correlate at Pearson r ≥ 0.89 across all models, with CodeAct’s gains “particularly for Perception tasks, merely reflect[ing] the deterministic precision of code-based calculations” [3].

Read that last clause carefully, because it is the whole design argument in one sentence. Where code execution helps, it helps because arithmetic done in code is exact and arithmetic done in a forward pass is not.


More resolution, worse reasoning

The finding that should shape what you send is about data density.

Across tasks, performance rank correlates negatively with both input sequence length (Spearman −0.55, p = 2.1e-07) and sampling frequency (Spearman −0.53, p = 6.4e-07), with each point representing the 16-model average Kappa and six confounded tasks excluded to isolate the effect [3]. The authors summarise it as “longer input sequences and higher sampling frequencies correlate with worse performance.”

This is a correlation across a task set rather than a controlled experiment on one task, so read it as a strong directional signal rather than a dose-response curve. The direction is unambiguous, and it runs against the instinct to preserve resolution wherever possible.

What the working version looks like

The strongest published counterexample to “just give it everything” is not a bigger prompt. It is a smaller prompt with tools attached.

PHIA, Google’s Personal Health Insights Agent, answers questions about wearable data using multi-step reasoning, code generation and web search rather than by ingesting the series. It was evaluated over 650 hours of human expert assessment covering more than 6,000 model responses with 19 annotators, plus automatic evaluation of 16,000 responses, against two released benchmark datasets of over 4,000 questions [4].

The result is usually quoted as a single number. The three-way comparison is more useful:

ApproachAccuracy on objective numerical queries
Numerical reasoning, no tools21.6%
Code generation baseline74.4%
PHIA, full agent loop84.2%

Most of the distance is covered by simply letting the model write code instead of doing arithmetic in a forward pass: 21.6% to 74.4%. The agent framework adds roughly ten points on top of that. On open-ended questions PHIA earned 83% favourable ratings and was twice as likely to earn the highest quality rating [4].

Two caveats the paper states and most coverage drops. PHIA was evaluated on a single base model, Gemini 1.0 Ultra, which the authors chose deliberately to isolate the effect of the agent framework and could not vary because 650 hours of human evaluation is expensive. And the wearable data was high-fidelity synthetic data sampled from anonymised production data, not live user records. Neither undermines the finding; both mean the specific percentages travel less well than the architecture does.

The mechanism is the point. The model never does the arithmetic. It decides what to compute, writes code to compute it, reads the result, and turns that into language. Numbers come from execution. Sentences come from the model.

That division removes the sequence-length penalty, because the series never enters the context. It makes the numeric path inspectable, because generated code can be tested and constrained in a way a forward pass cannot. And it collapses the token cost, because the prompt holds a question and a few results rather than a month of samples.

But tools are necessary, not sufficient. Every model in HEARTS already had a code interpreter, and 16 of them still landed between 0.47 and 0.69 against a naive baseline of 0.61, while purpose-built models averaged 0.84 on the comparable subset. So “give the model a code interpreter” is the floor, not the answer. What the model is asked to compute, and what it is given as context to interpret the result against, is doing more work than the interpreter is.

The strongest objection to this post

PHIA argues for tools, not for buying a derived-metrics layer, and it would be sleight of hand to let the first stand in for the second. So, plainly:

If your data sits in a warehouse and you can attach a code interpreter to it, PHIA’s architecture works directly on raw data. For teams with that engineering already in place, that is a real and reasonable path and you do not need to buy an aggregation layer to take it.

What has changed since the first draft of this post is how much that route gets you on its own. HEARTS evaluated 16 frontier models with exactly that setup and found small gains over a naive baseline, weak correlation with general reasoning ability, and heavy reliance on low-complexity heuristics [3]. The interpreter solves the arithmetic problem. It does not supply the thing the models were missing, which is knowing what normal looks like for this person.

That is where a derived layer earns its place, and it is narrower than a marketing page would claim: when the semantic context has to be in the prompt, because a baseline, a percentile or a deviation is what turns a number into a finding, and when producing those baselines reliably across sources that disagree, with gaps, duplicates and inconsistent units, is itself the hard part.

If you have the pipeline and the interpreter, take the PHIA route and compute the baselines yourself. The part of this post that holds either way is that the raw series does not belong in the context window, and that specialized models beat prompted ones at deriving values, whoever builds that layer.


What that makes worth building

Concretely, the difference between two representations of the same night. Raw, as it arrives:

{"id":"123e4567-e89b-12d3-a456-426614174003","parentId":null,"value":62,
 "unit":"bpm","source":"Apple Watch","recordingMethod":"RECORDING_METHOD_AUTOMATICALLY_RECORDED",
 "deviceType":"Watch7,2","startDateTime":"2026-08-28T02:15:00+00:00",
 "endDateTime":"2026-08-28T02:20:00+00:00","additionalProperties":{}}

112 tokens, times 288 for one night of heart rate. Now the same night after the numeric work has happened:

{"date":"2026-08-28","sleep":{"score":0.61,"vs_baseline":"-0.14","duration_min":388,
 "baseline_min":452,"onset":"01:40","onset_baseline":"23:50","regularity":"low",
 "resting_hr":62,"resting_hr_baseline":57,"source":"Apple Watch","coverage":"complete"}}

81 tokens against 32,256, and the second is the version models answer well from, because every comparison they would otherwise have to derive is already stated. vs_baseline is the entire Deduction step lifted out of the forward pass. coverage exists so a gap in the data cannot be read as a value.

Which makes the work worth doing mostly unglamorous:

  • Provenance and deduplication. A model shown overlapping step counts from a phone and a watch will confidently add them. We covered why summing sources is the wrong operation; an LLM does not change that arithmetic, it just makes the error fluent.
  • Explicit missing data. A gap and a zero look identical once serialised, and a model reads absence as a value.
  • Baselines per user. The comparison is the insight, and handing over an absolute number and hoping the model works out whether it is unusual is asking for exactly the multi-step temporal reasoning the benchmark says it does not do.
  • Units and timezones normalised before serialisation. Ordinary data engineering that becomes an invisible failure mode when the consumer generates plausible text regardless of input quality.

How you would know it is working

One HEARTS finding invalidates the usual shortcut: benchmark performance is “only weakly related to general reasoning scores,” and the authors conclude that scaling alone does not resolve what they found [3].

So you cannot pick a model for this by leaderboard position, and you cannot assume the next release fixes it. A feature that depends on reasoning over health time series needs its own evaluation set, from your data and your users’ questions, scored against answers you computed independently.

That is more work than reading a benchmark table, and it is the only thing that tells you whether the feature works. It is also the step most often skipped on the way to a demo that convinces because the output is fluent.


What this does not solve

Fluency is not correctness. A well-structured input makes a wrong answer read better, not worse. User-facing health claims still need a bounded set of things the model may assert.

Aggregation is itself a modelling decision. A daily sleep score is a compression with opinions in it, and a model inherits those opinions cleanly and states them confidently. Which is why it matters how your derived layer is built, and what validation actually means for a health score.

And you may not be permitted to do any of this, depending on the source. Strava’s API Policy names ingestion into a context window as a prohibited act, Oura prohibits it for aggregators, Garmin permits it subject to disclosure and consent. That question comes before the architecture question, and it is covered in six licences, three incompatible rules.


The short version

One night of heart rate at five-minute resolution is 32,256 tokens. The same night summarised is 81. Thirty days of raw data is between one and 3.7 million tokens depending on sampling, against 132,000 as daily biomarkers.

That is the cheap argument. The real one is that on a 110-task benchmark, 16 frontier models already equipped with a code interpreter scored 0.69 at best against a naive baseline of 0.61, while purpose-built models averaged 0.84 where the best LLM managed 0.54. Performance fell as sequence length and sampling frequency rose. And the authors report that placing the data in the prompt directly would render 40 to 60 percent of their tasks unmeasurable, which is the token problem stated by people with no product to sell.

Compress because the answers get better. The token bill falling is a side effect.

Disclosure. Sahha sells the derived layer this post argues for, so judge the argument against its sources rather than against us. HEARTS and PHIA are independent of Sahha, the token counts are reproducible from the schema in our public docs with any o200k_base tokenizer, and the objection section above is the honest version of where this reasoning stops supporting us.

References

  1. Sahha Logs API, DataLog object schema. Sahha documentation. Retrieved 29 August 2026. https://docs.sahha.ai/docs/products/logs
  2. Sahha Biomarkers, 100+ standardized metrics across sleep, activity, vitals, body composition, nutrition and engagement. Sahha documentation. Retrieved 29 August 2026. https://docs.sahha.ai/docs/products/biomarkers
  3. HeaRTS: Benchmarking LLM Reasoning on Health Time Series. Li S, Xiao S, Joshi M, Metwally A, McDuff D, Wang W, Yang Y. University of California, Los Angeles and Google Research. arXiv:2603.06638. Figures cited from Table 2, Figures 4 and 5, and Appendix C.7 of the version dated 30 June 2026. https://arxiv.org/abs/2603.06638
  4. Merrill MA, Paruchuri A, Rezaei N, Kovacs G, Perez J, Liu Y, Schenck E, Hammerquist N, Sunshine J, Tailor S, et al. Transforming Wearable Data into Personal Health Insights using Large Language Model Agents. Google. arXiv:2406.06464, and Nature Communications. Figures cited from the abstract and Section 4.3 of the version dated 9 September 2025. https://arxiv.org/abs/2406.06464

Related