Methodology

How it works

The formulas behind every score, with the numbers the app actually uses, so you can judge the estimates for yourself.

The scores at a glance

Exposure Radar turns everyday signals into four numbers. Each runs from 0 to 100, and all of them use the same colors, from green to red.

Readiness

How ready you are today. Higher is better.

Exposure index

How much contagious illness you were likely around on one day. Lower is better.

7-day exposure

Your recent exposure, with recent days counting most. Lower is better.

Immune readiness

Your vitals compared with your own baseline. 75 is your usual.

This page gives the exact formulas and numbers the app uses. The scores are estimates for personal awareness, not medical measurements, and they can’t tell you whether you’re sick.

Exposure index

Every place you spend time gets a dose: a relative number that grows with the time you spent there and with each factor that makes catching something more likely.

dose = hours × setting × crowding × community spread × climate × mask

A visit that crosses midnight is split between the two days. Each day’s doses are added up and turned into that day’s index, from 0 to 100. The factors are explained below.

Setting: 0.03 to 1.5

The type of place stands in for how well it’s ventilated and how close people usually are. The app looks up the nearest categorized point of interest within 75 meters on Apple Maps. Home is the place you’re most often at 3 a.m. (after at least two nights there), or any place you mark as home. You can change a place’s type in the app.

Place typeSettingTypical devices
Home0.032
Outdoors0.152
Office0.68
Hotel0.68
Shop0.710
Other indoor0.710
Food & drink1.015
Gym / arena1.015
School / library1.115
Theater / museum1.220
Transit hub1.320
Healthcare1.520

Home is set low because the app can only reflect community exposure there. It can’t see who you live with. “Typical devices” is the crowd count the app assumes when it couldn’t measure one.

Crowding: 0.5 to 2.5

When the app is open during a visit, it scans for 12 seconds and counts Bluetooth devices with a strong signal: −70 dBm or stronger, which is roughly 1 to 3 meters away in a typical room. A visit keeps the highest count seen. If a visit wasn’t scanned, the app uses the typical count for that type of place from the table above.

crowding = 0.5 + devices ÷ 20, with devices capped at 40

So 0 devices gives 0.5, 10 gives 1.0, 20 gives 1.5, and 40 or more gives 2.5. Only the count is kept, never device identifiers.

Community spread: 0.3 to 2.0

community spread = 0.3 + 1.7 × percentile ÷ 100

The percentile is the combined wastewater level for the county you were in, from 0 to 100 (see Community spread below). A visit keeps the level from the time you were there, so older days aren’t re-scored with today’s levels. With no data, this factor is 1.0.

Climate: 0.7 to 1.4

Dry air helps flu viruses survive and spread (Shaman and Kohn, 2009). The app measures dryness as absolute humidity: grams of water vapor per cubic meter of air (g/m³). It calculates this from the temperature (T, in °C) and relative humidity (RH, in %) that Apple Weather reports for where you were.

absolute humidity = 6.112 × e17.67 T ÷ (T + 243.5) × RH × 2.1674 ÷ (273.15 + T)

outdoors = 1.4 − 0.05 × absolute humidity, kept between 0.7 and 1.4
indoors = 1 + (outdoors − 1) ÷ 2, so between 0.85 and 1.2

Indoors, the effect is halved. Air with 8 g/m³ is neutral (1.0). A cold, dry day (0 °C and 60% humidity, or 2.9 g/m³) gives 1.25 outdoors and 1.13 indoors. A humid summer day (25 °C and 70% humidity, or 16.1 g/m³) gives 0.7 outdoors and 0.85 indoors. Without weather data, this factor is 1.0.

Mask: 0.3

If you note that you wore a mask at a place, that visit’s dose is multiplied by 0.3. Otherwise this factor is 1.0.

From dose to index

daily exposure index = 100 × (1 − e−dose ÷ 10)

The index climbs quickly at first, then flattens as it nears 100. A day’s total dose of 10 gives 63.

Day’s total doseIndexLevel
110Low
326Moderate
539Moderate
1063High
1578Very high
2086Very high

Levels: under 25 is low, 25–49 moderate, 50–74 high, and 75 or more very high.

A worked example

An evening concert. 3 hours 15 minutes in a concert hall (theater / museum), with 38 devices nearby, local wastewater at the 73rd percentile, and 4.2 g/m³ of absolute humidity.

  • hours: 3.25
  • setting: 1.2
  • crowding: 0.5 + 38 ÷ 20 = 2.4
  • community spread: 0.3 + 1.7 × 0.73 = 1.541
  • climate: 1.4 − 0.05 × 4.2 = 1.19 outdoors, so 1 + 0.19 ÷ 2 = 1.095 indoors
  • mask: none, so 1.0

dose = 3.25 × 1.2 × 2.4 × 1.541 × 1.095 ≈ 15.8
index = 100 × (1 − e−1.58) ≈ 79, very high

That one visit puts the day at about 79. With a mask, its dose would be about 4.7 and the index about 38.

7-day exposure

Your 7-day exposure is a weighted average of the last seven daily indexes. Each day counts 0.8 times as much as the day after it. Days with no logged places count as 0.

7-day exposure = Σ (indexd × 0.8d) ÷ Σ 0.8d, where d runs from 0 (today) to 6 (six days ago)

DayWeightShare of total
Today1.0025%
1 day ago0.8020%
2 days ago0.6416%
3 days ago0.5113%
4 days ago0.4110%
5 days ago0.338%
6 days ago0.267%

This is the exposure number on the Today screen, on the widget and in Family & Friends.

Community spread

Community spread comes from the National Wastewater Surveillance System (NWSS) run by the U.S. Centers for Disease Control and Prevention (CDC), which tracks virus levels in sewage from treatment plants across the country. The app downloads data for COVID-19, influenza A and RSV, plus measles detections, for the county you’re in. It finds the county with the FCC’s county lookup. If your county has no sewer sites in the data, it uses the sites across your state.

From samples to a percentile

  • For each sewer site, the app averages the samples from the site’s most recent 14 days.
  • It ranks that average against all of the site’s samples from the past year. The percentile is the share of the past year’s samples at or below the recent average.
  • A site counts only if it has a sample from the last 30 days and at least 8 samples in all. Sites are weighted by the number of people they serve.

Combining the viruses

combined = 0.6 × highest + 0.4 × average, using the COVID-19, influenza A and RSV percentiles
+ 10 (up to 100) if measles was detected in the last 3 weeks

Leaning on the highest value keeps one surging virus from being averaged away.

Levels and trend arrows

LevelPercentile
Minimalbelow 20
Low20–39
Moderate40–59
High60–79
Very high80 and above

Measles shows as detected or not. Trend arrows compare the average of the latest 14 days with the 14 days before: up if it’s more than 15% higher, down if it’s more than 13% lower.

Immune readiness

Immune readiness compares seven Apple Health signals with your own recent history. Overnight signals (respiratory rate and wrist temperature) and sleep count toward the morning you wake up.

SignalStrain whenWeight
Resting heart rateminimum spread 1.5 bpmhigher1.0
Heart rate variability (SDNN)minimum spread 4 mslower1.0
Sleeping wrist temperatureminimum spread 0.15 °Chigher1.0
Respiratory rate while asleepminimum spread 0.4 breaths/minhigher0.9
Blood oxygenminimum spread 0.7 percentage pointslower0.6
Sleepminimum spread 0.4 hourslower0.6
Stepsminimum spread 800 stepslower0.3

Step 1: your baseline

For each signal, the baseline is the median of your daily values from 60 days to 4 days before the day being scored. The 3 most recent days are left out, so a change that’s just starting doesn’t become part of its own baseline. At least 10 days of data are needed, which in practice means about two weeks of wearing Apple Watch.

Step 2: how far from your usual

z = (today’s value − baseline median) ÷ spread
spread = the larger of 1.4826 × MAD and the signal’s minimum spread

MAD is the median absolute deviation: the typical distance of your daily values from their median. Unlike a standard deviation, one odd day can’t throw it off. Multiplying it by 1.4826 puts it on the same scale as a standard deviation. The minimum spread keeps a very steady baseline from turning tiny changes into big numbers.

Step 3: point every signal the same way

Each z-score is flipped where needed, so that a positive number always means a change in the direction linked to strain: higher resting heart rate, respiratory rate or temperature, or lower heart rate variability, blood oxygen, sleep or steps. Each adjusted value is then kept between −2 and +4. That way one extreme reading can’t dominate, and better-than-usual readings can lift the score only a little.

Step 4: the score

immune readiness = 75 − 15 × (weighted average of the adjusted values), kept between 0 and 100

Only signals with data that day are included, and the weights are shared out among them. A score of 75 means you’re at your baseline. Because of the −2 to +4 limits, the lowest possible score is 15.

  • 80–100: above baseline
  • 65–79: at baseline
  • 50–64: mild strain
  • under 50: elevated strain

Example. Your resting heart rate this morning is 64 bpm. Your baseline median is 58 bpm, with a MAD of 1.5 bpm.

spread = the larger of 1.4826 × 1.5 = 2.22 and 1.5, so 2.22
z = (64 − 58) ÷ 2.22 ≈ 2.7

Say heart rate variability is also down, with an adjusted value of 2.0, and the other five signals are at baseline (0). All seven weights add up to 5.4.

weighted average = (1.0 × 2.7 + 1.0 × 2.0) ÷ 5.4 ≈ 0.87
immune readiness = 75 − 15 × 0.87 ≈ 62, mild strain

Strain signal

A core signal is “off” when its adjusted value is at least 1.5 (at least 1.0 for sleeping wrist temperature). The four core signals are resting heart rate, heart rate variability, respiratory rate and sleeping wrist temperature.

The app shows a strain signal, “Your vitals show signs of strain”, when either:

  • two or more core signals are off today, and two or more were off yesterday; or
  • three or more core signals are off today.

When new Health data arrives, the app checks in the background and sends a notification, at most once every three days. In the example above, resting heart rate (2.7) and heart rate variability (2.0) are both off. If two core signals were also off the day before, that’s a strain signal.

Studies of wearable data have found shifts like these around the start of infections (see Background reading). The same shifts also follow hard exercise, alcohol, a short night or stress. A strain signal means your vitals have changed, not that you’re sick. The app doesn’t detect or diagnose illness.

Readiness

readiness = 0.6 × immune readiness + 0.4 × (100 − 7-day exposure)

Your vitals describe how your body is doing now, so they count for more. Exposure is a risk that may never turn into illness.

  • During a strain signal, readiness is held at 40 or below.
  • Until your vitals baseline exists, the app assumes typical vitals: an immune readiness of 75.
  • Readiness appears once at least one place has been logged.
  • The app also tells you what’s holding readiness back most: immune readiness below 75, or 7-day exposure above 25, whichever costs more points.

Levels: 75–100 is Ready, 60–74 Mostly ready, 45–59 Take it easy, and under 45 Rest and recover.

Example. Immune readiness is 78 and 7-day exposure is 52.

readiness = 0.6 × 78 + 0.4 × (100 − 52) = 46.8 + 19.2 = 66, mostly ready

Event planning

When you choose an event from your calendar, the app sets a low-exposure window before it: 5 days by default, adjustable from 2 to 14. Five days covers the usual incubation time for flu (1 to 4 days), COVID-19 (about 3 days) and RSV (4 to 6 days).

  • Target: keep each day’s exposure index under 30 during the window.
  • Reminders: at 9 a.m. on the day the window starts, and 14 days before the event, because flu and COVID shots take about two weeks to reach full protection.
  • Destination: if the event has a location, the app finds its county and shows the wastewater levels there.

Limitations

  • Estimates, not diagnoses. The app can’t tell you whether you’re infected or contagious.
  • Wastewater is community-level. It describes a whole area, not you or the people near you. It lags by days, and not every county has sewer sites.
  • U.S. data. Community spread uses U.S. data sources. Where there’s no data, that factor is neutral (1.0).
  • Bluetooth counts are a proxy. One person may carry several devices, or none, and scans happen only while the app is open.
  • Place type is inferred from nearby map points, so it can be wrong. You can correct it.
  • Location can miss visits, especially without “Always” and Precise Location.
  • Vitals move for many reasons, including exercise, alcohol, travel and stress, and they depend on how consistently you wear Apple Watch.
  • A simplified model. The factor values are the developer’s estimates, informed by the research below. The app hasn’t been clinically validated.

Background reading

  1. Mishra T. et al. “Pre-symptomatic detection of COVID-19 from smartwatch data.” Nature Biomedical Engineering 4, 1208–1220 (2020). doi:10.1038/s41551-020-00640-6
  2. Quer G. et al. “Wearable sensor data and self-reported symptoms for COVID-19 detection.” Nature Medicine 27, 73–77 (2021). doi:10.1038/s41591-020-1123-x
  3. Radin J.M. et al. “Harnessing wearable device data to improve state-level real-time surveillance of influenza-like illness in the USA: a population-based study.” The Lancet Digital Health 2(2), e85–e93 (2020). doi:10.1016/S2589-7500(19)30222-5
  4. Shaman J. and Kohn M. “Absolute humidity modulates influenza survival, transmission, and seasonality.” Proceedings of the National Academy of Sciences 106(9), 3243–3248 (2009). doi:10.1073/pnas.0806852106
  5. U.S. Centers for Disease Control and Prevention. National Wastewater Surveillance System. cdc.gov/nwss

Exposure Radar isn’t affiliated with or endorsed by these authors or organizations.