By Dan · June 9, 2026
Three Things We Haven’t Figured Out
Most posts on this blog end with a working answer. This one doesn’t. These are three problems in Run Plan we’ve been at for a while and still don’t have clean solutions to. They affect real runners every day. We’re writing them down partly because being honest about open problems is useful, and partly because someone reading this might know something we don’t.
1. The current-pace window we keep changing
The Watch shows your current pace during a run. Behind that display is a sliding-window calculation: take the last N seconds of GPS samples, compute total distance over total time, format as min:sec per km. N is the only real knob.
We have been moving N around for a year.
- 30 s — too sluggish. Runner picks up the pace at the start of an interval and the display takes most of the interval to reflect it.
- 20 s — better. Calm display, but still felt slow at interval boundaries.
- 10 s — this week. Theoretically responsive enough to feel the runner’s pace change inside an interval. Possibly too jumpy when GPS hiccups.
- 5 s — tried it briefly. Twitchy. Pace shoots to 3:00/km for one second when a satellite drops, recovers, shoots somewhere else when the next one drops.
The outlier filter (we drop samples implying speeds above 10 m/s and samples with horizontal accuracy worse than 25 m) helps, but it doesn’t make the choice of N easy. We’ve shipped four different values across the last year.
The short version: we don’t have a principled answer. We don’t know how to evaluate “the pace display feels right” without putting it on real runners and asking them. Even then the feedback is “feels okay I guess” or “a bit jumpy today” depending on whether the day had GPS weather.
What would convince us we got it right: a way to compare different N values against the same recorded GPS track and have the runner mark, after the fact, “this is what the display should have said.” That dataset doesn’t exist. We could probably make it — record raw samples, replay them through the algorithm with different Ns, ask the runner to score — but it’s a meaningful chunk of UX work for an answer that might still be subjective.
For now: 10 seconds. Ask us next week.
2. Watch-to-iPhone sync that’s slow in ways we can’t reproduce
When the runner finishes a workout on the Watch, the app on the iPhone should reflect it within seconds. There’s a whole article about how this works: a live channel (WCSession.sendMessage), a deferred channel (transferUserInfo), and Apple Health’s own iCloud sync as a third path. Three channels means the runner usually sees the workout marked done in under a second.
Usually. Sometimes — we don’t have a clean handle on how often, but a non-trivial fraction of the time — none of the three lands the workout in the app within minutes. The runner pulls the phone out, taps the calendar, the workout isn’t there. They tap a refresh button (yes, we added a refresh button). Sometimes that pulls the workout from HealthKit. Sometimes it doesn’t and the runner has to force-quit the iPhone app and reopen.
We don’t know what triggers the slow path. Suspect list:
- The iPhone is asleep enough that WCSession is not reachable, the deferred queue is full of older items, and the OS deprioritises new ones.
- HealthKit’s iCloud sync is having a bad day. Apple Health on the iPhone can lag the same workout by 30+ minutes when iCloud is degraded; we’ve seen it correlate with App Store outages.
- Our HealthKit observer query is hitting a background-runtime limit we’re not detecting.
- WatchConnectivity itself silently drops messages during certain iOS/watchOS version pairings (we’ve watched this happen historically).
- Something we haven’t guessed.
We can’t reliably reproduce it. We’ve added logging that paints a partial picture in our own usage but doesn’t give us a smoking gun. The refresh button is the workaround. It works, mostly, but it’s a workaround. A runner who just finished an interval workout doesn’t want to be tapping refresh buttons.
What would convince us we got it right: zero refresh-button taps required across a month of runs. We’re not there.
3. Bad GPS leaves holes in the route map
The Watch records location during a run and we draw a polyline over a map. When GPS holds steady the route is clean. When GPS doesn’t — tunnels, dense urban canyons, the bit of Amsterdam where the trees overhang the path — the line either skips across the gap as a straight diagonal or just stops and resumes.
Neither is good. The straight diagonal lies about where the runner went. The visible break makes the runner think the app stopped recording, which it didn’t — GPS did, the Watch kept logging steps and heart rate the whole time.
What we’ve tried:
- Smoothing across gaps — draw a smooth curve that interpolates. Looks nicer; lies more. Some runners noticed and complained.
- Distinct line style for low-confidence segments — dashed for “we’re guessing”. Visually noisy but at least honest. Some runners didn’t notice the distinction.
- Plain breaks where GPS was lost — current behaviour. Honest, but reads as “the app stopped working.”
The deeper problem is that “here’s where you ran” is being asked to also mean “here’s how confident we are about where you ran,” and a polyline isn’t great at carrying both signals at once.
What would convince us we got it right: a runner whose Watch loses GPS for ninety seconds during a tunnel sees a route map that they don’t complain about and don’t misread. We’re not close. If you’ve seen another app do this well — particularly the visual treatment of uncertainty in a recorded track — we’d like to know.
Why we’re telling you
Run Plan’s blog has mostly been a series of war stories with the war won by the end of the article. That makes for satisfying reads and a slightly dishonest portrait of what indie product work actually looks like. The three problems above are not at the end of their arcs. They might never have clean ends — pace display is genuinely a taste question, and GPS uncertainty is a real-world physical constraint, not a bug. The sync one we’d like to nail and don’t know how.
If any of this resonates — you’ve solved one, you’ve seen a paper on it, you know what we’re missing — we’re both reachable. The contact email is on the home page. Every message gets read.