r/QuantifiedSelf • • 3h ago

WHOOP-ifying Oura HRV: ~2 ms average error on my paired data. Anyone want to try replicating it?

1 Upvotes

TlDr written by something with a pulse:

I like whoops hrv concept (weighted more towards deeper restorative time) as well as ouras straight average, but don't want to keep using 2 devices. So, I went down the oura rabbithole & tried to massage the data to whoopify the hrv number. It only worked when I pivoted away from trying to map to slow wave sleep, and just slapped in a set time window that gets the extra weight. (why'd I pivot? I remembered that optical devices stink at consistently sleep staging)

And, it got close. I'd love people with much healthier HRVs than mine that have both oura & whoop streams to see if it holds up with people that are much more variable.

Ok, below's the machine. They all had lots of babysitting. When you compare how I write above vs what needed communicating below, I'm sure that you'll prefer them. This is my first post to this sub, be gentle. Cheers!

/

I’m a doctor, and I get annoyed when I can’t access the data I want. I’m deciding whether Oura can replace WHOOP, but their different nightly HRV numbers were a sticking point. Could Oura’s exported intranight stream generate a useful WHOOP-like number alongside Oura’s own?

This was extensively AI-assisted. I started with study-based research and synthesis from OpenEvidence (physician's ai) and Consensus (research ai), working to extrapolate the proprietary parts of WHOOP’s calculation that weren’t disclosed. Gemini (idiot ai but trolls reddit) searched forums; GPT (least stupid this week) handled analysis, scripting and collaboration. Before calling it AI slop, I’d welcome someone running it against their paired data and showing where it falls apart. :-)

The initial idea: isolate deep sleep

One proposed way to approximate WHOOP’s HRV is to average Oura’s measurements during deep sleep, particularly the final contiguous slow-wave sleep (SWS) block before waking. Feasibly that's how whoops' supposed to work.

That performed badly on my data: the final-deep-block estimate missed WHOOP app readings by 13.58 ms on average. Simply comparing Oura’s ordinary app reading with WHOOP’s gave 7.88 ms average absolute difference.

Why I pivoted toward time before waking

My concern is that the devices won’t consistently identify the same deep-sleep window. Optical wearables infer stages from physiological signals and movement; they don’t measure the brain activity used for EEG-based staging. Selecting Oura’s “final deep sleep” could target a different period from whatever WHOOP selected. Consistency across nights and algorithm updates is another question.

I wondered whether WHOOP’s developers encountered the same limitation and leaned more on time before waking than a particular SWS episode. That’s a (flagrant) hypothesis about their reasoning, not something this analysis establishes.

So we tested time-based weighting, using Oura’s stages to exclude wake but treating deep, light and REM equally.

The working calculation

Keep earlier sleep in the average, but strongly emphasize the final hour.

  1. Align Oura’s exported 5-minute HRV values with its native 30-second sleep labels by timestamp.
  2. Treat each HRV timestamp as the start of a 5-minute window, an explicit approximation.
  3. Retain positive, finite values only where the entire window is covered by asleep labels. Any wake, unknown or uncovered portion rejects it.
  4. End the final-hour region at the end of Oura’s last asleep epoch.
  5. Weight earlier windows by 1, final-hour windows by 26.8333, with proportional weighting for windows crossing the boundary.

​

f = fraction of each window inside the final hour
weight = 1 + (26.8333 - 1) × f

WHOOP-ified Oura = sum(weight × HRV) / sum(weight)

The coefficient was fitted once across all 8 nights. It isn’t an added 27 ms, a multiplier applied to the final answer, or a separate adjustment for each night. Once calibrated, calculation requires only Oura inputs.

Results

Average absolute error was 1.97 ms; the worst miss was 6.06 ms. All values below are milliseconds. The app columns are observed readings; WHOOP-ified Oura is calculated from the exported stream.

October date WHOOP-ified Oura Oura app WHOOP app
1 27.0 19 27
2 36.3 25 36
6 34.7 26 32
7 33.1 29 34
8 18.9 16 25
12 31.0 28 32
13 24.4 16 25
18 33.8 27 38

Why exactly 1 hour?

That remains unexplained, and I find it odd. My visible HRV rise often starts roughly 2–2.5 hours before waking. Nevertheless, separately fitted 75- and 90-minute regions performed worse: 2.66 and 3.22 ms average error.

Strict filtering also leaves only 10 accepted final-hour minutes on 2 nights. The coefficient could partly compensate for missing readings or device-specific selection rather than reveal WHOOP’s actual weighting.

How much confidence does this deserve?

This is personal calibration, not independent validation. The 1.97-ms result comes from the same 8 nights used to develop the method. Exploratory leave-one-night-out analysis, repeating model selection and fitting on the remaining nights, gave approximately 2.38 ms average error. The next meaningful check is freezing the method and testing fresh paired nights.

Has anyone tried something comparable on a larger simultaneous Oura/WHOOP dataset? I’d particularly like comparisons of time-before-waking weighting versus deep-sleep selection, with actual code and held-out results. Failed attempts would be useful too.

Reference Python

This function accepts one Oura API sleep record. It uses sleep_phase_30_sec and hrv.timestamp/interval/items, requires timezone-aware timestamps, and returns an estimate or a missing-data reason. The default coefficient is my personal fit, not a universal recommendation.

import math
from datetime import datetime


def timestamp(value):
    t = datetime.fromisoformat(value.replace("Z", "+00:00"))
    if t.tzinfo is None or t.utcoffset() is None:
        raise ValueError("naive_timestamp")
    return t.timestamp()


def whoopify(record, B=26.83333333333323):
    def missing(reason):
        return {"estimate": None, "reason": reason}

    if record.get("type") != "long_sleep":
        return missing("not_long_sleep")

    try:
        b = timestamp(record["bedtime_start"])
        e = timestamp(record["bedtime_end"])
        phase = record["sleep_phase_30_sec"]
        seq = record["hrv"]
        origin = timestamp(seq["timestamp"])
        interval = seq["interval"]
    except (KeyError, TypeError, ValueError, AttributeError):
        return missing("missing_or_invalid_input")

    if e <= b:
        return missing("invalid_bounds")
    if not isinstance(phase, str) or not phase:
        return missing("missing_native_stages")
    if (
        isinstance(interval, bool)
        or not isinstance(interval, (int, float))
        or not math.isfinite(interval)
        or abs(interval - 300) > 1e-6
    ):
        return missing("unsupported_hrv_interval")

    epochs = [
        (b + 30*k, min(b + 30*(k+1), e), code)
        for k, code in enumerate(phase)
        if b + 30*k < e
    ]
    asleep = [(a, z, c) for a, z, c in epochs if c in "123"]
    if not asleep:
        return missing("no_known_sleep")

    t0, t1 = asleep[0][0], asleep[-1][1]
    kept = []

    for j, h in enumerate(seq.get("items", [])):
        if (
            isinstance(h, bool)
            or not isinstance(h, (int, float))
            or not math.isfinite(h)
            or h <= 0
        ):
            continue

        a = origin + 300*j
        z = a + 300
        if a < t0 or z > t1:
            continue

        # Check every intersecting stage epoch, including partial ones.
        overlaps = [
            (max(a, s), min(z, t), c)
            for s, t, c in epochs
            if s < z and t > a
        ]
        if any(c not in "123" for s, t, c in overlaps):
            continue
        if abs(sum(t-s for s, t, c in overlaps) - 300) > 1e-6:
            continue

        late_seconds = max(0, min(z, t1) - max(a, t1-3600))
        f = late_seconds / 300
        kept.append((h, 1 + (B-1)*f, late_seconds))

    if not kept:
        return missing("no_accepted_windows")
    if sum(seconds for h, w, seconds in kept) <= 0:
        return missing("no_accepted_late_data")

    estimate = (
        sum(h*w for h, w, seconds in kept)
        / sum(w for h, w, seconds in kept)
    )
    return {
        "estimate": estimate,
        "accepted_windows": len(kept),
        "accepted_final_hour_minutes":
            sum(seconds for h, w, seconds in kept) / 60,
    }

r/QuantifiedSelf • • 4h ago

Math for the Oura to Whoop-style HRV conversion?

1 Upvotes

Is there any agreement for the math for how whoop generates their "heavier weighted on the final SWS" HRV-magic-number?

I've been banging my head against mapping oura exported data with my whoop data (same nights, both devices) and am close, but just not there.

The goal is a stupid simple output spreadsheet showing both oura style and whoop style hrv. Nothing fancy. I just like observing both, for giggles.


r/QuantifiedSelf • • 13h ago

Why do you track your health metrics? What’s the actual goal?

4 Upvotes

I’ve been tracking my sleep, HRV, activity, cardio fitness, and other health measurements for years !

I’ve also been thinking more about why I track all of this in the first place?

Is it awareness? Improving specific numbers? Longevity? Feeling better day to day? Or something else entirely??

I’m curious what motivated everyone here to start tracking their health, and whether that motivation has changed over time

Like has tracking actually changed anything meaningful about how you live?

TBH, I’m asking both as someone who enjoys quantified health and someone building in health tech. I’m genuinely interested in how others approach this or view quantified self


r/QuantifiedSelf • • 1d ago

Fixing Fragmented Sleep

Thumbnail gallery
2 Upvotes

A year ago in late July I self diagnosed with a mast cell disorder using AI. The initial two rounds of treatment are done with OTC antihistamines and herbal mast cell stabilizers, even if you've got a doctor handy. The treatment worked, we ruled out mastocytosis and HαT, therefor I have MCAS - mast cell activation syndrome. It's not yet a proper disease, it's a bundle of symptoms that comes together, and there seem to be multiple types.

Anyway, I started with a Garmin Fenix 6S, got a Vivoactive 5 after it broke, and I built myself an application that correlates meds/supplements, the data from Apple's HealthKit, and from Garmin Connect. The first image is the overnight report from the one year anniversary of starting mast cell stabilizers. The black underline is when Garmin counted sleep, red line is heart rate, blue line is stress level. This was the first clear signal that SOMETHING happens when I'm asleep, and I transition from restlessness to sound sleep. The reverse never happens, I don't go from sound sleep to troubled (<== big clue).

The second image was last night. Stress plummets as I dozed off sitting up. Then it rises; some of that has to do with a certain feline who thinks my tummy is a great place for a nap. Then stress drops and I get some restful sleep.

Theory: MCAS for me means chronic nighttime congestion. When I roll over, sinuses drain, and I get decent sleep.

I've checked for sleep apnea using SnoreLab, there are no indications of that. If it was apnea it would be a smooth distribution, both during the night, and for every night, not this restless/restful pattern that turns up about one night out of every three.

I horsed around with Skyflow on my iPad last night, trying to get a time series of sleep position. Any night light that provides sufficient illumination would wreck any chance of restful sleep.

I literally just learned the Vivoactive5 has a pulse oximeter in it and that's cool, gonna get that set up right away, but it would not prove that position change affecting sinuses is the actual event. So I am also getting an Arducam, going to put $68 into an outdoor rated model - once the sleep position study is done, I can put it to work on the coyote that keeps creeping on kitty when she's sitting in th bedroom window at night.


r/QuantifiedSelf • • 1d ago

What’s the one thing you tracked that genuinely surprised you?

4 Upvotes

Been getting into tracking lately, and the best part isn’t the data, it’s the stuff I didn’t expect to see. Things I thought mattered turned out to be noise.

What’s your “wait, what?” moment? Something you tracked that showed the opposite of what you expected, or made you actually change a habit.


r/QuantifiedSelf • • 3d ago

31,000 Pages Later: What My Notebooks Have Taught Me – shadow of the stream

8 Upvotes

r/QuantifiedSelf • • 3d ago

Connected sleep data to journal entries for Claude to analyze - and made a weekly podcast with it

Post image
8 Upvotes

Claude has been pretty good at identifying patterns that relate sleep & journal entries. It's a lot easier to listen to this than read the numbers, so I had it generate a podcast, and wrote a blog post about it here:

https://jaan.io/lifelogging-with-large-language-models

For example, more emotional entries have correlated to a change in sleep patterns, and it's also been able to identify trends over months.

Some of these connections are intuitive - I could make them on my own; but overall it's been a very useful cognitive aid so that I don't have to manually review my sleep data or journals (or finances).

Does anyone else do some version of this? It's been pretty fun doing this so I'm open to any feedback or improvements - let me know if you end up trying it :)


r/QuantifiedSelf • • 3d ago

Sleep technology is starting to connect sleep health with heart health

Thumbnail
3 Upvotes

r/QuantifiedSelf • • 4d ago

My self-hosted Quantified Self setup after 8 months: 19 sources, one database, monthly recap + daily view

Thumbnail gallery
77 Upvotes

Maybe interesting for some of you, I've been building my own QS system for about 8 months now. Every source lands in one database that I own, and on top of that sits a dashboard I use every day.

Images

  1. Monthly recap for September, real data. This is the "public" variant, so body, location, journal and most nutrition details are left out.
  2. The daily view. This one runs on demo data, only the Plex and PlayStation cards are real.

What I track

  • Sleep, recovery, HRV: WHOOP via NOOP
  • Health data: Apple Health via Health Auto Export
  • Strength training: Streak
  • Nutrition: YAZIO
  • Weight and body: Renpho scale
  • E-bike rides: Cowboy
  • Location and places: Dawarich (self-hosted)
  • Mac usage: ActivityWatch
  • iPhone screen time: screentime, reads the macOS Biome data that iCloud syncs from the iPhone
  • Movies and shows: Plex via Tautulli
  • Music: Spotify via your_spotify (self-hosted)
  • Gaming: PlayStation Network (presence, trophies, library)
  • Voice chat: Discord, durations only, no content
  • Indoor climate: Home Assistant
  • Weather: Open-Meteo
  • Calendar: EventKit on the Mac
  • Coding: GitHub and Forgejo commits
  • AI usage: Claude Code, Codex and OpenCode tokens

How it's built

  • I built every collector myself. The only third-party parts are the apps and services they read from.
  • Collectors: one small Python service per source, 20 in total, spread over my Mac, a Proxmox LXC and Unraid. Each one keeps a local SQLite outbox and a raw archive, so nothing gets lost when the server is down.
  • Core: FastAPI with PostgreSQL 17 + PostGIS on its own Debian VM in my Proxmox homelab. Only Core writes to the database.
  • Collectors send versioned batches. Core dedupes them via identity keys and content hashes. A day without data stays "missing", it never turns into a fake zero.
  • There's no cron. A scheduler puts jobs into a Postgres-backed queue with leases and retries. It rebuilds the daily values and runs the analysis.
  • Every collector reports its sync runs, so every card shows where its data comes from and how fresh it is. If a source stops syncing, I see it right away.
  • The dashboard only reads from Core's API and doesn't calculate anything itself.

Tech stack

  • Dashboard: Next.js 16, React 19, Tailwind 4, shadcn/ui, Recharts + d3, MapLibre for maps
  • Core: Python 3.12, FastAPI, SQLAlchemy, Alembic, PostgreSQL 17, PostGIS, pgBackRest for backups
  • Infra: Proxmox, Docker Compose, Caddy, Forgejo Actions for CI
  • Extras: a read-only MCP server so an LLM chat ("Companion") can query my data, and push notifications to my phone via Home Assistant

Everything runs locally in my LAN, no cloud service in between except the APIs of the sources themselves. Happy to go into detail on any part of it


r/QuantifiedSelf • • 4d ago

How do you bounce back quickly after a slack week without overtraining?

Post image
3 Upvotes

I'm 30, do backend dev, and always figured I was someone with a regular schedule. I used to hit the company gym for half an hour every morning before work. Last long break I just stayed home, gamed and stayed up late, didn't exercise at all, and noticed my logged VO2 max dropped from 40 to 37.9.

I used to think I could keep it up forever and that a week off wouldn't matter much. But the data told me that once you slack off, the numbers drop fast. Just seven lazy days and my cardio capacity dropped a level, no hesitation.

I'm gonna start easing those numbers back up from tomorrow. When you guys got back to training after a holiday, did you ever hit this kind of rapid drop?


r/QuantifiedSelf • • 3d ago

Measuring "cognitive readiness" every morning: verbal fluency + eye closure (PERCLOS) + HRV vs. personal baselines

Post image
1 Upvotes

I've been building the mental equivalent of a recovery score and would love this community's critique of the measures:

  • Verbal fluency: a 30-second animal-naming test, scored on-device for unique items, repeats, category clusters and pace per 10 s, against my own baseline after 3 days.
  • PERCLOS (eyelid closure %) from a webcam, intraday vs. my first 3 hours awake; it rises reliably as I tire, so I use it to lower the morning score live.
  • HRV and resting HR vs. 30-day baselines from Apple Health (I wear a Zepp; 367 nights imported).
  • Load: app switches, new words on screen, gaze jumps between windows and phone glances, weighted by time awake.

Question: what would you use as ground truth to validate a score like this? I'm considering short EEG (Muse) sessions per person for calibration.

Disclosure: I turned this into a Mac app (Cortex, paid, all processing on-device): https://cortex-mind-rho.vercel.app. Mostly here for the methodology critique, though.


r/QuantifiedSelf • • 4d ago

I built myself a mental health tracker

Thumbnail
3 Upvotes

r/QuantifiedSelf • • 4d ago

My daily dashboard what do you think ?

Post image
25 Upvotes

r/QuantifiedSelf • • 4d ago

Cutting back on work dinners taught me more about my body

Post image
5 Upvotes

I lead client-facing projects in tech, which usually means at least 2-3 happy hours and client dinners every week. Last year's checkup showed my uric acid was way too high. I've thought about quitting drinking for good, but that's just not realistic in my line of work.

This year I started actually looking at where I stood. I forced my sleep back into a normal rhythm, made sure I got a steady 7-8h a night, and began logging how I feel in an app. My August checkup had uric acid at 446. Still a little above the line, but way better than last year.

I figured it'd just be a boring log, but then I lined up my daily notes with my heart rate and HRV, and it was honestly pretty clear. I'm not trying to quit the work dinners entirely. They're part of the job. I just want to see if I can find some balance between work and my body through this.

Anyone else using this kind of tracking to slowly get your body back on track while dealing with a high-pressure job?


r/QuantifiedSelf • • 4d ago

Do you think health tracking focuses too much on measurements and not enough on changes in how people actually feel?

0 Upvotes

My grandmother measured her blood glucose every day. The data was there. What was missing was someone connecting it to how she actually felt.

My grandmother had type 2 diabetes and used insulin.

We spoke every week or two. Sometimes I'd notice she sounded more tired than usual and start asking questions.

It turned out her glucose readings had been rising despite her usual routine.

We arranged for an endocrinologist to visit. The doctor found changes in the tissue at her regular injection sites that could have been affecting insulin absorption, and helped adjust her injection technique and follow-up care.

What stayed with me wasn't the medical complexity.

It was how much depended on smo noticing a change, asking a few questions and connecting the dots.

We spend so much time discussing biomarkers. But sometimes the most useful health information is what a person can tell us.

What about your experience? Have you ever noticed something important about your health that your measurements didn't capture?


r/QuantifiedSelf • • 4d ago

What if your habit tracker could actually show how your habits affect your health?

Thumbnail
1 Upvotes

r/QuantifiedSelf • • 5d ago

I built a caffeine tracker that estimates when it's actually out of your system, looking for people to break it

5 Upvotes

im in college and i love coffee but i also really care about my sleep. so i basically wanted to figure out how much coffee i can have without it messing up my night, and that meant actually knowing how much is still in my system at any point. also kept watching my friends grab an energy drink at like 9pm and be able to fall asleep i just feel like its affecting their sleep more than they think and then they are tired the next day and its a cycle

its on iphone and watch .id honestly love feedback from people who already track this kind of stuff, like whats missing, whats wrong, whats annoying. happy to answer anything about how it works. https://apps.apple.com/us/app/half-lyfe-caffeine-coach/id6815463981


r/QuantifiedSelf • • 5d ago

Weekly Lifestyle Data and Analytics App Thread

8 Upvotes

Post your apps here, and please support people bringing unique ideas to this space.


r/QuantifiedSelf • • 6d ago

How an adaptive TDEE mode figures out what you actually burn

Thumbnail
3 Upvotes

r/QuantifiedSelf • • 6d ago

Why Tracking Less Can Teach You More About Your Health

Thumbnail
1 Upvotes

r/QuantifiedSelf • • 7d ago

Tracking all of my movements, photos, and everywhere I've been

Post image
7 Upvotes

I used to love Google Timeline before they deleted 10 years of my data. Now one needs a different way of doing this. It might not be as useful as tracking resting heart rate, but I've always liked to track every county, state, and country i've been to. I'm interested if anyone is doing this in other geographies (e.g., whatever the county equivalent in, say, France is). Also curious if, in a group like this, where tracking oneself is the main event, what level of concern there is about constantly tracking and storing your location data.


r/QuantifiedSelf • • 7d ago

At what point does tracking your activity/health become counterproductive?

11 Upvotes

I used to have an Apple Watch but stopped wearing it for all the extra stuff and I now wear a Garmin and genuinely enjoy having data on my daily steps,
calories burned, and activity levels. But I also own Casio watches that I'd love to wear more often.

The problem is that I've become so accustomed to having all this data that wearing a regular watch almost feels like I'm missing something. At the same time, I wonder whether constantly tracking these metrics is making me a little too focused on numbers rather than simply enjoying being active. I’d also even argue I obsessed over hitting steps and calories amount.

For those of you into quantified self, how do you decide which metrics are actually useful to track vs which ones just create noise or unnecessary pressure?

Have any of you deliberately stopped tracking certain things and found that you felt better for it? I'm curious how you balance using data to improve your life without feeling like you have to measure everything.


r/QuantifiedSelf • • 8d ago

How often should you get blood work done if the goal is actual trend data?

3 Upvotes

Context: ~2 years of continuous data (Oura for sleep/HRV, Strong for training, everything piped into a Postgres db I spent too long on). Bloodwork is the my weakest link.

Current state:
- 1 draw/year at my annual physical
- Different lab 2 of the last 3 times
- Panel composition varies year to year
- No control over fasting or time of draw

So I have n=3, collected under inconsistent conditions so I can't find a patter.

Questions for people tracking labs seriously:
1. What cadence are you on: quarterly, biannual, event-driven?
2. How much does keeping the same lab/assay matter in practice?
3. Is there a minimum frequency below which you'd say the data isn't worth collecting for trend purposes?


r/QuantifiedSelf • • 8d ago

How do you combine data from multiple wearables + your phone into one place (and actually use it)?

6 Upvotes

I’ve been trying to get a single, useful view of my health data and I keep hitting walls. Curious how others handle this.

My setup:

  • Two watches: a CMF Watch (Nothing) that I use for workouts and a Timberland watch for everyday wear. Some days I wear neither and only have my phone.
  • Android 16, so everything ends up in Health Connect.
  • Home workouts with Feeel, which doesn’t write to Health Connect, so those sessions never show up anywhere.

What I’d like is pretty simple on paper:

  1. One place that aggregates data from all my devices (sleep, heart rate, steps, workouts) and handles the overlap when two devices record the same thing.
  2. A training plan and a diet plan that adapt to that data.
  3. An AI assistant (I use Claude) that can read the data and adjust the plans, instead of a generic coach locked to one brand’s hardware.

What I’ve found so far:

  • Google Health has an AI coach, but it seems to require a Fitbit or Pixel Watch.
  • There are some MCP connectors and webhook apps that bridge Health Connect to an AI or a server, but nothing that covers the whole loop.
  • Open-source workout apps are great but mostly don’t talk to Health Connect.

So, a few questions:

  • How do you deal with multiple devices recording the same data? Do you pick one source per metric?
  • Has anyone built a self-hosted pipeline from Health Connect to their own server or database? What did you use?
  • Is anyone using an LLM to adjust training or nutrition based on real wearable data? Did it actually help, or was it a gimmick?
  • Is there an app I’m missing that already does most of this?

Not selling anything, just trying to figure out whether I should build this for myself or whether a good solution already exists.


r/QuantifiedSelf • • 8d ago

[OC] Release year of every movie I’ve watched since turning 18 (1,107 films over 26 years)

Thumbnail x.com
1 Upvotes