In September, Apple said Apple Watch Series 12 measures heart rate “every five seconds, all day long” [2]. Its own accuracy study adds the detail that matters to developers: background readings reach HealthKit every 30 seconds, “to manage device memory” [1]. That is 2,880 heart rate values a day, ten times the ceiling of earlier watches, before a single workout.
At the other end, WHOOP’s developer API has no time series at all. A day arrives as four summary records, a cycle, a recovery, a sleep and a workout, holding about 40 values between them: recovery score, resting heart rate, HRV, sleep stage totals, strain, heart rate zone durations and so on [6].
Both are “one user”. The difference between them is more than two orders of magnitude, and it decides how a health product should ingest, store and compute. We counted what one user generates through each common route, what a year of it costs to keep, and where the real costs are. They are not where most teams look.
How much data does each wearable send in a day?
Take one user with a full day of wear, eight hours of sleep and a one-hour workout:
| Route | What arrives | Resolution | Values a day |
|---|---|---|---|
| WHOOP API | Cycle, recovery, sleep and workout summaries [6] | One record each, no time series | About 40 |
| Apple Watch before Series 12, HealthKit | Background heart rate | About one attempt every 5 minutes while still [3] | Up to 288 |
| Oura API | Heart rate, HRV during sleep, activity class | 5 minutes [5] | About 670 |
| Apple Watch Series 12, HealthKit | Background heart rate, HRV, a one-hour workout | 30 seconds, up to every 5 minutes, 5 seconds in workouts [1][2][3] | About 3,900 |
| Garmin Health API | Heart rate, stress, activity epochs | 15 seconds, 3 minutes, 15 minutes [4] | About 6,300 |
| Fitbit at 5-second resolution | Heart rate, as used in research studies | 5 seconds [7] | 17,280 |
These are counts of values, not records. A Garmin daily summary is one record containing up to 5,760 heart rate values, and one HealthKit sample can hold a series [3]. For WHOOP, which has no time series, the count is every measurement in its four summaries. For the others it is the fast-moving time series alone; their own summary fields, steps, energy, sleep stages, SpO2 and temperature add more. The point is the range, not the decimal.
Two things stand out. First, the richest data does not come from the most expensive device; it comes from the route. Apple’s study notes that not all manufacturers write high-fidelity data to HealthKit at all [1], so the same watch read through Apple Health and through its maker’s cloud can differ by orders of magnitude. Second, the trend is up. Apple went from 288 background readings a day to 2,880 in one hardware generation, and HRV from a reading every few hours to “as often as every five minutes” [2][3].
How much storage does a year of wearable data need?
A year of all-day Garmin data is about 2.3 million values per user. A Series 12 owner who works out daily produces about 1.4 million.
How much space that takes depends almost entirely on how it is stored:
| Storage approach | Bytes per value | One Garmin user, one year | 100,000 users, one year |
|---|---|---|---|
| One PostgreSQL row per value, with an index | About 110 | About 260 MB | About 26 TB |
| Compressed columnar time series | About 2 | About 5 MB | About 0.5 TB |
The row figure is arithmetic, not a benchmark. PostgreSQL stores a 23-byte header and a 4-byte pointer for every row [8]; add a user ID, a timestamp, a metric type, a value and a source, align it, and index it by user, metric and time, and each value costs about 110 bytes before any bloat. Compressed columnar formats exploit the fact that wearable series are regular and change slowly: Facebook’s Gorilla time series engine averaged 1.37 bytes per data point [9]. Two bytes is a conservative figure.
At list prices that is the difference between roughly $3,000 a month for a year of data in managed database storage, at $0.115 per GB-month [10], and about $11 a month in object storage at $0.023 per GB-month [11]. Both numbers are small next to a health product’s other costs, and the first grows every month you keep raw data in the wrong place. The design rule is simple: keep raw values cheap and immutable, and keep only what the product reads in the expensive store.
Where do the real costs come from?
Volume is the obvious number. These five cost more.
1. Summaries that are sent again and again. Garmin delivers each day’s summary more than once. Its specification says an updated record shares the user, start time and type of an earlier one, with an equal or longer duration, and that “your integration should replace old records with the updated summary” [4]. A watch that syncs a dozen times a day sends the day’s growing heart rate map a dozen times. If syncs are evenly spaced, the values transferred add up to about 6.5 times the day’s final data. Ingestion has to be an idempotent upsert keyed by user, source, type and start time, or it doubles counts.
2. Recompute storms. If every incoming notification triggers a full recalculation of that user’s scores, a user who syncs 12 times a day across five data types triggers 60 recalculations for one day of data. Most products need one or two. Coalesce updates per user and day, wait for a quiet period, then compute.
3. Rate limits that end polling. Oura allows an application 5,000 requests per 5 minutes [5]. Polling four endpoints once an hour for every user uses that up at 15,000 users. Oura’s own advice is a single historical request when a user connects, then webhooks, which arrive about 30 seconds after data syncs from the app [5].
4. Windows that close. Garmin’s specification says data is removed from the Health API seven days after it is first loaded, and that notifications for an app on hold are queued for up to seven days and then dropped [4]. An outage longer than a week means lost data unless you can backfill, and on Garmin’s reopened program historical data is an Enterprise feature. We covered that in Garmin’s new API tiers.
5. Mornings. Oura notes that sleep data needs the user to open the app [5]. Sleep therefore arrives when people wake up, not evenly through the day. A product whose users share a time zone, such as an employer program in one country, receives most of a day’s sleep in a few morning hours. If 60% of sleep records arrive between 06:00 and 09:00, the busiest hour carries about five times the average load. Size for the morning, not the mean.
How much of it does a product need?
Very little of the raw stream, most of the time:
| Feature | Resolution it needs |
|---|---|
| Daily scores, streaks, goals | Daily summaries |
| Resting heart rate and HRV trends | One value per night |
| Sleep timing and regularity | Sleep start and end times |
| Intraday charts | 1-minute or 5-minute aggregates |
| Heart rate zones in a workout | 1 to 5 seconds, during the workout only |
| Research, model training, new algorithms | Raw values |
Reducing 15-second heart rate to 5-minute means cuts 5,760 values a day to 288. Reducing it to a nightly resting value cuts it to one. The raw data still matters, because a better algorithm next year needs it to recompute history. It just does not belong in the database that serves the app.
Size your own pipeline
The figures above are for one user. To size a real system, put your own mix through six formulas. The example is a 20,000-user product where half the users wear an Apple Watch Series 12, 30% a Garmin and 20% an Oura ring; the sync counts are assumptions to replace with your own.
| Output | Formula | Example |
|---|---|---|
| Values per day | Users on each source × that source’s values per day, summed | 10,000 × 3,900 + 6,000 × 6,300 + 4,000 × 670 = 79 million |
| Storage per year | Values per day × 365 × bytes per value | 3.2 TB as database rows at 110 bytes; 58 GB compressed at 2 bytes |
| Notifications per day | Users × syncs a day × data types per sync, summed | Garmin 6,000 × 12 × 5, Apple 10,000 × 24 hourly uploads, Oura 4,000 × 8 = about 630,000, 7 a second on average |
| Busiest hour | Notifications per day × share arriving in the morning window ÷ hours in the window | If 40% arrive in three morning hours: about 84,000 an hour, three times the average |
| Polling load | Users × endpoints × polls an hour ÷ 12, per 5 minutes | Oura, 4 endpoints hourly: 1,333 requests per 5 minutes, 27% of the 5,000 limit, which runs out at 15,000 Oura users |
| Recalculations per day | Notifications per day without coalescing; about one or two per user with it | 630,000 against 20,000 to 40,000 |
Two conclusions hold for almost any mix. Storage is a rounding error once raw data is compressed. The numbers that need engineering are notifications, the morning peak and recalculations, and each of them grows with how often devices sync, not with how much data they carry.
An architecture that holds at 100,000 users
- Land raw data once, immutably, in compressed columnar files partitioned by user and day, in object storage.
- Upsert, never append, keyed on user, source, data type and start time, because providers replace their own records.
- Debounce computation per user and day, so twelve syncs produce one recalculation.
- Serve aggregates, such as daily biomarkers, nightly values and 5-minute series, from the operational database.
- Use webhooks with a reconciliation job that checks for missing days well inside each provider’s retention window.
- Budget each provider’s rate limit as a shared resource, and alert before it runs out, not after.
- Keep provenance with every value, so a recalculation can tell which source and which version produced it.
How much data one wearable user generates is not one number. It runs from a few dozen values a day to tens of thousands, and it is rising with every hardware generation. Storing it is cheap if it is stored well. What decides whether a health data pipeline survives scale is everything around the bytes: re-sent records, recalculation, rate limits, closing windows and the morning rush.
References
- Apple. Apple Watch Heart Rate Accuracy Study. September 2026. https://www.apple.com/health/pdf/Heart_Rate_Accuracy_Study_2026.pdf
- Apple. Apple advances health and fitness capabilities using Apple Intelligence. Apple Newsroom, 9 September 2026. https://www.apple.com/newsroom/2026/09/apple-advances-health-and-fitness-capabilities-using-apple-intelligence/
- Crosley, B. Five-Second Heart Rate: What Changes for HealthKit Apps. https://blakecrosley.com/blog/five-second-heart-rate-healthkit
- Garmin. Health REST API Specification, version 2.9.6. https://pdfcoffee.com/healthrestapispecification296worldwide-pdf-free.html
- Oura. Oura API Documentation, version 2. Retrieved 27 October 2026. https://cloud.ouraring.com/v2/docs
- WHOOP. WHOOP Developer API reference. Retrieved 27 October 2026. https://developer.whoop.com/api/
- Zhang, Y., Folarin, A. A., Sun, S., et al. (2024). Longitudinal assessment of seasonal impacts and depression associations on circadian rhythm using multimodal wearable sensing: retrospective analysis. Journal of Medical Internet Research, 26, e55302. https://doi.org/10.2196/55302
- PostgreSQL Global Development Group. Database Page Layout. PostgreSQL Documentation. https://www.postgresql.org/docs/current/storage-page-layout.html
- Pelkonen, T., Franklin, S., Teller, J., et al. (2015). Gorilla: A fast, scalable, in-memory time series database. Proceedings of the VLDB Endowment, 8(12), 1816-1827. https://www.vldb.org/pvldb/vol8/p1816-teller.pdf
- Amazon Web Services. Amazon RDS for PostgreSQL pricing. Retrieved 27 October 2026. https://aws.amazon.com/rds/postgresql/pricing/
- Amazon Web Services. Amazon S3 pricing. Retrieved 27 October 2026. https://aws.amazon.com/s3/pricing/
- Sahha. When to Use Data Logs vs Biomarkers. https://sahha.ai/guides/biomarkers-vs-datalogs/