Problem RestatementProblem
Apple asked a systems-level question: design the sensing subsystem of a smartwatch. Choose sensors, decide sampling rates, decide where processing happens (on the watch, on the phone, in the cloud), and balance accuracy against battery life (the watch should last all day or more). Features include step counting, workouts, heart rate, sleep and fall detection.
Sensors and Typical Rates
| Sensor | Used for | Typical rate |
|---|---|---|
| Accelerometer | Steps, activity type, fall detection, wrist raise | 25–100 Hz (bursts up to 800 Hz for falls) |
| Gyroscope | Workout form, gestures | 50–100 Hz, only when needed (power-hungry) |
| Optical heart rate (PPG) | Heart rate, blood oxygen | 25–100 Hz while measuring, periodic in background |
| Barometer | Floors climbed, elevation | ~1 Hz |
| GPS | Outdoor workout routes | 1 Hz during workouts only (very power-hungry) |
| Skin temperature | Sleep, cycle tracking | Every few minutes |
Rule: sample only as fast as the feature needs, and turn expensive sensors on only when needed.
Architecture (on the device)Architecture
%%{init: {"look":"handDrawn","handDrawnSeed":7,"theme":"base","fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","themeVariables":{"fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","fontSize":"16px","primaryColor":"#fff4e6","primaryBorderColor":"#1e1e1e","primaryTextColor":"#1e1e1e","secondaryColor":"#e7f5ff","tertiaryColor":"#ebfbee","lineColor":"#1e1e1e","textColor":"#1e1e1e","mainBkg":"#fff4e6","nodeBorder":"#1e1e1e","clusterBkg":"#f8f9fa","edgeLabelBackground":"#ffffff","classText":"#1e1e1e"}}}%%
flowchart LR
S["Sensors"] --> HUB["Low-power sensor hub (always-on coprocessor)"]
HUB -->|"buffered batches / events"| AP["Main processor - apps, algorithms"]
HUB -->|"wake on event: fall, raise"| AP
AP --> STORE[("Local health store")]
AP -->|"sync when connected"| PHONE["Phone app"]
PHONE -->|"encrypted backup / sync"| CLOUD["Cloud"]- Sensor hub: a tiny low-power chip that reads sensors continuously and runs simple algorithms (step counting, wrist-raise detection, fall-detection triggers). The main processor sleeps most of the time, which is the biggest battery saver.
- Batching: the hub buffers samples and hands them over in batches (e.g., every few seconds or minutes) instead of waking the main CPU for each sample.
- Event wake-ups: important events (a possible fall, a workout start) wake the main processor immediately.
Deep Dive — Where the sensor data gets processedDeep dive
Accelerometers, heart rate and GPS produce continuous streams. Every byte that leaves the watch costs battery, and the radio is the most expensive component on it.
Stream raw samples to the phone
Send the 100 Hz accelerometer stream and every heart-rate reading to the phone as they arrive.
%%{init: {"look":"handDrawn","handDrawnSeed":7,"theme":"base","fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","themeVariables":{"fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","fontSize":"16px","primaryColor":"#fff4e6","primaryBorderColor":"#1e1e1e","primaryTextColor":"#1e1e1e","secondaryColor":"#e7f5ff","tertiaryColor":"#ebfbee","lineColor":"#1e1e1e","textColor":"#1e1e1e","mainBkg":"#fff4e6","nodeBorder":"#1e1e1e","clusterBkg":"#f8f9fa","edgeLabelBackground":"#ffffff","classText":"#1e1e1e"}}}%%
flowchart LR
ACC["Accelerometer 100 Hz, 3 axes"] --> RAW["Raw samples over Bluetooth"]
RAW --> RADIO["Radio active almost continuously"]
RADIO --> BATT["Battery drained in hours"]
RAW --> DEP["Nothing works when the phone is absent"]
DEP --> FALL["Fall detection fails on a walk without the phone"]The radio dominates the power budget, so continuous streaming is the single most expensive thing the watch can do. It also makes every feature dependent on the phone being present — unacceptable for safety features.
Batch the raw data and send it periodically
Buffer samples on the watch and transmit every few minutes.
The radio now wakes in bursts instead of staying on, which is a genuine improvement — duty-cycling is where most of the saving is. But the volume is unchanged, so storage and transmission still scale with raw sample rate, and latency-sensitive features still cannot work until the phone processes the batch.
Process as early as possible, send summaries
%%{init: {"look":"handDrawn","handDrawnSeed":7,"theme":"base","fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","themeVariables":{"fontFamily":"Virgil, \"Segoe Print\", \"Comic Sans MS\", cursive","fontSize":"16px","primaryColor":"#fff4e6","primaryBorderColor":"#1e1e1e","primaryTextColor":"#1e1e1e","secondaryColor":"#e7f5ff","tertiaryColor":"#ebfbee","lineColor":"#1e1e1e","textColor":"#1e1e1e","mainBkg":"#fff4e6","nodeBorder":"#1e1e1e","clusterBkg":"#f8f9fa","edgeLabelBackground":"#ffffff","classText":"#1e1e1e"}}}%%
flowchart LR
S["Sensors"] --> WATCH["On the watch: steps, heart rate, fall detection, live workout metrics"]
WATCH --> SUM["Summaries - per minute, per workout, per event"]
SUM --> PHONE["On the phone: sleep stages, longer trends, sync"]
PHONE --> CLOUD["Cloud, with consent: long-term history, backup, model improvement"]
WATCH --> LOCAL["Works with no phone - latency and safety features intact"]
SUM --> RADIO["Radio wakes rarely, sends kilobytes not megabytes"]- Run the latency- and safety-critical algorithms on the watch. Fall detection and live workout metrics must not depend on a phone being in range, and step counting is cheap enough to do in place.
- Send summaries, not streams. A minute of 100 Hz three-axis data is thousands of samples; the step count and heart-rate summary for that minute is a few dozen bytes. That ratio is the whole power argument.
- Use the phone for what needs more compute — sleep staging over a whole night, longer trend analysis — where battery and processing are far less constrained.
- The cloud is optional and consented, for history, backup and population-level model work. Nothing the user relies on day to day should require it.
Keep short windows of raw data on the watch for the cases that genuinely need it — a workout the user wants analysed in detail — and discard the rest. Raw data is worth keeping only where something will actually consume it, which is the same trade the storage tiering makes, decided here at the point of capture.
Algorithms (simple explanations)
- Step counting: filter the accelerometer signal, detect peaks with a regular rhythm (about 1–3 steps per second), and ignore arm movements that aren't walking.
- Heart rate (PPG): green LEDs light the skin, and a sensor measures reflected light that pulses with blood flow. Motion adds noise, so use the accelerometer to cancel motion artifacts and track the heart-rate frequency over time.
- Fall detection: a hard impact (high acceleration spike) followed by no movement → ask the user "Are you OK?" and call emergency services if there's no response.
- Adaptive sampling: higher rates during workouts, lower rates during rest or sleep.
Battery, Accuracy and Privacy
- Battery budget per feature: GPS and continuous PPG are the biggest costs, so use them only when needed (workouts, and periodic background checks).
- Accuracy is validated against reference devices (chest straps, lab equipment) across skin tones, wrist positions and activities.
- Health data is encrypted on the device and in sync, and the user controls what is shared.
Wrap-UpWrap-up
Choose sensors and sampling rates per feature, and run always-on sensing on a low-power sensor hub that buffers data in batches and wakes the main processor only for important events. Process on the watch for real-time features (steps, heart rate with motion-artifact removal, fall detection), on the phone for heavier analysis, and in the cloud only for opt-in history. Adapt sampling to activity, use GPS and PPG sparingly for battery, validate accuracy broadly, and protect health data end to end.