---
title: "Why a Fifteen Minute Idle Sleep Swallowed Our One-Off Refresh Request"
canonical: https://dxdev.com/blog/refresh-gate-served-open-pages-only/
datePublished: 2026-09-12
---
The status page behind our "what closed recently" view is supposed to update within seconds. The answer we got was two and a half days old. The data had been generated two mornings earlier and covered only two of the days since, while closed work kept piling up on top of it.

We checked the most obvious suspect first, the background watcher. It was alive. Its heartbeat was healthy, and its log showed it stepping its own polling cadence up and down all evening, exactly as designed. It checks every few seconds right after something happens, then backs off to every fifteen seconds, then a minute, then five minutes, and finally every fifteen minutes once things go quiet. A healthy process, watching on a cadence that gets slower the longer nobody's around.

## Healthy watcher, broken gate

So the bug wasn't whether the watcher was running. It was what decided whether the watcher rebuilt the snapshot on a given pass. That decision came down to one check: had something asked for a refresh inside the last several seconds. A page left open keeps re-asking every few seconds on its own, so it almost always lands inside that window whenever the watcher happens to look.

A one-off request, the kind a script or a tool sends once and then stops, asks exactly once. Unless the watcher's loop woke up within that same short window, the ask was already stale by the next check. Once the watcher had backed off to its slowest cadence, the next check might be fifteen minutes away. Repeat that enough times and a snapshot that should be seconds old sits for days, because nothing about the watcher ever looked broken.

## Where the gate came from

The check was copied, on purpose, from an existing check built for a different page. That page behaves like a dashboard someone leaves open, where "asked in the last few seconds" is a safe proxy for "someone is looking at this right now." The assumption holds for a page that keeps re-touching the flag by itself. It fails for a feature that also gets one-off questions from scripts and automated tools. Nothing separated the two cases in testing, since both look identical until a request goes unanswered long enough for someone to notice.

## The fix

The gate had to stop asking "was it asked recently" and start asking "has anything asked since the last actual refresh." That is a comparison between two timestamps, when the last ask came in and when the last refresh happened. It replaces a moving window that can expire before the watcher gets around to checking it. Whatever cadence the watcher is on when it next wakes, fast or slow, it catches up on any pending ask exactly once and goes back to idle. Worst-case staleness becomes one full idle sleep instead of open-ended.

The original window check stayed. It kept its narrower, correct job of deciding whether the watcher should speed up because someone is actively around. It just stopped gating whether a refresh happens.

We added tests for the edge this exposed. An old, already-served ask does nothing on its own. A fresh ask gets served exactly once no matter how long it waited. No ask on record does nothing. Then we checked against the real running process instead of trusting the tests alone. We touched the ask flag and waited about twenty seconds. The live watcher was already running the fixed code, since it restarts itself whenever its own source changes, and it rebuilt the snapshot on its very next cycle.

While in that part of the code we also found a small stray file, a crash artifact from an unrelated tool, that had been sitting tracked in the repository for weeks. Different bug, same shape: something got written once, nothing watched for it afterward, and it sat there being true and stale at the same time. We removed it in the same pass.

The whole thing, from diagnosis to a verified production fix, took about thirty-eight minutes, most of it spent reading the gate rather than rewriting it.

## What a live heartbeat doesn't tell you

A watcher that's alive and a feature that's working are separate claims. If you rely on a live status page or report, test it with a one-off request while nobody is watching, because the open-tab case will pass either way.
