I wrote a plateau detector for my body. It found things I didn't expect.
· Mason Walters
There’s a small line under the weight chart on my /health page that reports how many plateaus the algorithm found in my own data. I wrote the code behind it. The first time I loaded the finished page, I scrolled back up to re-check the dates — because I didn’t remember being in half of them.
I wanted a definition of “plateau” that survives two-data-points-a-month sampling. What I shipped is fifteen lines of Ruby: anchor on the first weigh-in, walk forward, and keep the plateau alive as long as every later weigh-in stays within 2 lbs of the anchor. The first reading that drifts past 2 lbs closes the run and becomes the new anchor. If the closed run lasted at least 3 weeks, record it.
Both numbers — 2 lbs, 3 weeks — I picked, then argued with myself about.
2 lbs is about the day-to-day swing I see at my size from hydration, glycogen, and gut contents. Define a plateau tighter than that and you’re calling noise a signal; define it looser and you’re calling a real 3-lb drift a plateau. 2 lbs is the narrowest band that sits mostly above the noise floor.
3 weeks is shakier, and I’ll own it. On a 1st-and-15th schedule, 3 weeks guarantees at least three weigh-ins inside the run — two points is a coincidence, three is a trend. Four weeks would’ve been more defensible. I went with three because I wanted the detector to find something, and a 5-week floor would’ve found almost nothing in five years of data. That’s a bias. I’m writing it down so it’s on the record.
Run across all 135 weigh-ins back to October 2020, the obvious plateaus landed where I expected: a long flat stretch right before a cut, a shelf at the top of a bulk where the climb stalled and then resumed.
The ones I didn’t remember were the interesting ones. In each, the data said I’d held within 2 lbs for a month or more, and my memory said I was making progress. Memory lost. The chart had been sitting there the whole time; I’d just never asked it the right question.
And the shape of that problem is one I see at work constantly. A revenue cohort holds flat for six weeks while the rest of the business grows — is it a stable cohort, a saturated channel, or a metric that silently broke upstream and stopped updating? You want the detector that flags it early, not the one that surfaces it after the quarter closes and someone asks in a meeting why nobody caught it. Same three failure modes, too:
- False positives. A travel week where I just didn’t weigh in reads as “stayed within 2 lbs,” because there’s no data point to disagree. I’ve got exactly one of those in the run.
- False negatives. A real plateau the algorithm misses because one bad reading — miscalibrated scale, sodium-heavy late dinner — pushed a weigh-in past the threshold and reset the anchor.
- Late detection. A 3-week minimum means I learn I’ve stalled after three weeks of stalling. Useful in hindsight, useless for “change something this week.”
The honest summary is that detecting a plateau in a sparse, noisy signal is hard, and a fifteen-line heuristic is a starting point, not an answer. A daily weigh-in stream would let me fit a rolling slope with a confidence interval, which is what I’d actually want. The data I have doesn’t support it. So the detector that exists is the one with two numbers I half-guessed.
I keep it in production anyway, because the version that exists is better than the version I keep meaning to write. That’s also true of most production code.
Found this useful or want to push back on it? Say hi.