The easy-day specialist

The Zone 2 ride that stays easy.

Power changes as your body responds. Zone2 watches your heart rate and quietly adjusts your smart trainer to help keep the ride in your easy aerobic band — so you finish the ride you intended, not one you accidentally raced.

Available on iPhone & iPad · heart-rate strap & smart trainer over Bluetooth

Heart rate — settling in your easy band Trainer power — free to adapt as your body responds
Normal ERG locks the watts, so your heart rate drifts upward as you warm up and fatigue. Zone2 flips it: it steers from heart rate and lets the power move.

What you get

Stays easy

Effort, not watts

Pick a band and pedal. Zone2 progressively adjusts the trainer to help keep your heart rate in the easy aerobic zone — and backs off faster than it pushes.

Safety-biased

Handled faults ease down

A hard heart-rate ceiling, an internal command limit, and a lost-signal rule keep handled control faults from chasing harder power. Those safety decisions live in a tested core, not the UI.

Yours

Private & local

No account, no servers, no tracking. Your rides stay on your device. Write to Apple Health if you want; export a standard FIT file any time.

Your band

Three clear setup paths

Use an observed maximum from Apple Health, estimate from your age, or enter a maximum heart rate you already know. You confirm the band before it is saved.

For experienced cyclists Stop turning recovery and endurance rides into tempo. Zone2 backs off ERG power automatically when cardiac drift arrives, so the easy day remains the easy day — no watching HR and nudging the trainer down yourself.

Built in the open

Zone2's decision-making — the controller and the safety invariants — lives in a portable, I/O-free core that the same tests exercise from Rust, Python, and Swift. I wrote up how it works, what the research says, and what I got wrong along the way, plus a small set of real (scrubbed) ride data so you don’t have to start from nothing like I did.

Read the build notes & science → Sample data on GitHub →