Smooth Live Pace Display
Why raw instant pace flickers like a broken stopwatch, how Garmin solved it with 5-second rounding, and how we built a calm pace display that updates only when it matters.
Live pace on a walking app should be the simplest thing in the world. Distance divided by time, formatted as minutes per mile or per kilometer. One number, updated continuously. Easy.
Except it flickered. Every second, the displayed pace would jump — 12:15, then 12:42, then 12:08, then 12:35. A sawtooth pattern, degrading between pedometer updates and snapping back when new distance data arrived. Technically accurate at each instant, practically useless as information. We had built a number that was correct but unreadable.
The sawtooth problem
The root cause was a timing mismatch. Our session timer ticked every second, incrementing elapsed time smoothly. But CMPedometer — Apple’s pedometer API — delivers distance updates every 2 to 5 seconds. Between those updates, the numerator (time) kept climbing while the denominator (distance) stayed frozen. Pace is time divided by distance, so the displayed value drifted upward between each pedometer tick, then snapped back down when fresh distance arrived.
The visual effect was a sawtooth wave. Quick degradation, sharp correction, quick degradation, sharp correction. Over and over, once per second, for the entire walk.
This isn’t unique to our app. It’s a fundamental problem with any pace display derived from asynchronous data sources. GPS watches face the same issue — as Fellrnr documented across 12,000+ miles of testing, GPS-based instant pace can swing more than a minute per mile from the true value. Consumer GPS is accurate to 15–30 meters at best. When you’re dividing noisy distance by smooth time, the result inherits all the noise.
DC Rainmaker described the experience succinctly: one second it’s 7:30/mile, the next it’s 7:50/mile, even if you didn’t change your actual pace.
There’s a nuance worth noting: our pace is derived from CMPedometer, not GPS. Apple’s pedometer uses the motion coprocessor — an accelerometer, essentially a built-in footpod. It’s inherently more stable than GPS because it calculates distance from step count multiplied by stride length, not satellite triangulation. But it still delivers data in batches every 2–5 seconds, and for walking — where you cover only 4–5 meters between updates compared to 8–12 for running — the sawtooth is proportionally worse. Smaller distance increments mean each timer tick shifts the pace/distance ratio by a larger percentage.
Every app handles this differently
We looked at how every major running and walking platform deals with live pace before deciding on our approach.
Strava sidesteps the problem entirely. Their live display shows split average pace — the cumulative average for the current kilometer or mile — not instantaneous pace. Split averages are naturally stable because both numerator and denominator grow together. It’s clever, but it means you’re always looking at historical data, not current performance.
Apple Watch offers three distinct pace metrics: average pace (cumulative), current pace (short-term smoothed, algorithm undocumented), and rolling mile (pace over the most recent mile, only available after the first mile). The layered approach gives runners options but adds complexity — three numbers that often disagree with each other.
Garmin treats “instant pace” as a rolling average with a window of approximately 20–30 seconds on modern firmware, rounded to 5-second increments on the display. Their community has built open-source alternatives — the Rolling Average Pace Connect IQ data field offers configurable distance-based (100m default) or time-based (60s default) windows using a circular buffer.
The consensus across the industry: no implementation shows truly instantaneous pace. Every single one applies some form of smoothing, averaging, or gating. The question isn’t whether to smooth, but how.
Why flickering numbers are worse than no numbers
A flickering pace display isn’t just annoying — it’s cognitively expensive. Research on perceptual-cognitive performance during exercise shows that while moderate physical exertion can improve reaction speed, it doesn’t improve accuracy. At higher intensity, accuracy declines. And here’s the critical finding: the working memory benefit of exercise is cancelled out when additional cognitive tasks are performed simultaneously.
Processing a rapidly changing number is an additional cognitive task. Every time the pace display updates, your brain has to read the new value, compare it to the previous one, decide whether the change is real or noise, and update your mental model of how fast you’re going. When the number changes every second, that’s a continuous cognitive tax layered on top of the walk itself.
Nielsen Norman Group calls this the display inertia problem — when content changes faster than users can cognitively process, they either miss the update entirely or feel stressed trying to keep up. For a runner or walker glancing at their wrist for 1–2 seconds, a flickering number is functionally meaningless. You see a value, but you don’t know your pace.
The data backs this up. Runners Connect reports that 33% of runners discontinued wearable use because the feedback wasn’t useful, and when runners become fixated on hitting specific numbers, performance can drop by up to 10%. Unstable displays create a worst-of-both-worlds scenario: the number is present enough to demand attention but too noisy to inform decisions.
How Garmin solved this
Garmin has been dealing with this problem for years, and their solution is elegant: round the displayed pace to the nearest 5 seconds.
On the Forerunner 935, Fenix series, and many other models, the pace display shows 4:00/km or 4:05/km, but never 4:02/km. The underlying data in the FIT file records full-resolution values, but the display — the thing a runner actually looks at mid-stride — steps in 5-second increments.
As one Garmin community member put it: “Real-time pace displayed to the second will never be accurate as long as it’s derived from GPS, so steps of 5 seconds are perfectly fine.”
This works because of how humans set pace goals. Research by Pope and Simonsohn (2011) in Psychological Science demonstrated that round numbers on performance scales act as powerful psychological reference points. Baseball players with a .299 batting average were almost twice as likely to get a hit in their last at-bat of the season compared to players at .300. SAT students were 20% more likely to retake the test when their score ended in 90 rather than 00.
Runners think in round numbers. Sub-5:00/km. Sub-6:00/mile. The four-minute mile isn’t famous because 3:59.4 is a physiologically meaningful threshold — it’s famous because it’s a round number, as analysis of the Bannister barrier suggests. Rounding pace to 5-second increments aligns the display with how people naturally evaluate their performance: am I above or below my target?
What we changed
Two fixes, applied together.
Fix 1: Only recalculate when distance changes. Instead of recomputing pace on every timer tick, we now track the last distance value that triggered a pace update. When the pedometer delivers fresh data, we check if sessionDistance has actually changed. If it hasn’t, we skip the recalculation entirely. This eliminates the sawtooth — pace holds steady between pedometer updates because we’re not dividing increasing time by stale distance.
Fix 2: Round to the nearest 5 seconds. When we do recalculate, the raw pace gets rounded to the nearest 5-second increment. A raw pace of 12:37 displays as 12:35. A raw pace of 12:38 displays as 12:40. The rounding formula is simple: convert to total seconds, add 2 (for rounding rather than truncation), integer-divide by 5, multiply by 5.
let totalSeconds = Int(rawMinutesPerUnit * 60)
let rounded = ((totalSeconds + 2) / 5) * 5
We also raised the cold-start threshold. The previous version showed pace after 50 meters of distance. The new version requires both 100 meters and 30 seconds of elapsed time before displaying any pace value. Until then, the display shows --:--. The first few seconds of a walk produce wildly unstable pace values — you’ve walked 10 meters in 5 seconds, which extrapolates to a pace that means nothing. Better to show nothing than to show noise.
Precision where it matters
Rounding is the right choice for a live display that you glance at mid-walk. But it’s the wrong choice for the recap screen, where you’re reviewing your completed session at rest.
The distinction maps to what Willy et al. (2020) found about feedback modalities in running: real-time visual feedback during exercise can “overload visual perception and cognitive processing capacities,” but post-exercise review is a different context entirely. You’re stationary, focused, and have unlimited time to process the data.
So we split the pace into two properties. averagePace is the live display value — smoothed, rounded, updated only on distance changes. exactAveragePace is the recap value — unrounded, computed from the final session totals. The recap screen now calls exactAveragePace, giving you the precise 12:37/km that you earned, not the 12:35 you saw during the walk.
This follows the same pattern Garmin uses. Their FIT files store full-resolution data. Their watch faces show rounded values. The live display serves glanceability; the post-session data serves analysis.
The result
Field-tested on an 8,000+ step walk over 78 minutes. The pace display is stable and calm. It updates every few seconds when the pedometer delivers new distance, steps in 5-second increments, and holds steady between updates. No sawtooth. No flicker. You glance at your wrist and you know your pace.
The cold start works cleanly — --:-- for the first 30 seconds and 100 meters, then a smooth transition to a real value. Pause and resume don’t break the calculation. The recap screen shows the precise final pace.
What we learned
The instinct when building a live data display is to show maximum precision at maximum frequency. Real-time means every second, right? And pace means to-the-second accuracy, right?
Neither turns out to be true for a display you read while walking. What Stryd calls the “smoothing window” problem applies to every real-time athletic metric: shorter windows are more responsive but noisier, longer windows are smoother but lag behind reality. For pace, the pedometer’s natural 2–5 second update interval provides a reasonable window, and 5-second rounding absorbs whatever noise remains.
The deeper lesson is about the difference between data and information. Raw pace-per-second is data. Smoothed, rounded pace that updates when distance changes is information. A display that flickers every second contains more data but communicates less. A display that steps calmly in 5-second increments contains less data but tells you exactly what you need to know.
Mark Weiser’s calm technology framework, which we’ve referenced before in this devlog, applies here too. The pace display should inform without demanding. It should live in your periphery during a walk — available when you glance, invisible when you don’t. A flickering number demands attention. A stable number permits it.
The fix was 22 lines of code. The improvement is every second of every walk.