Randomized Polling Offset¶
Scheduling method — instantiates Synchronized Release Dampening
Gives each periodic client a fixed, individually-randomized phase offset so their identical poll intervals stop landing on the same tick.
When many clients poll on the same interval, the danger isn't the interval — it's the phase. A fleet that all polls "every 60 seconds" is harmless if the polls are smeared across the minute and catastrophic if they all fire on the top of it. Randomized Polling Offset attacks the phase directly: each client draws a stable offset within the period once, so client i polls at k·period + offsetᵢ, and the fleet's identical intervals fan out into a flat, continuous trickle. Its defining move — and what separates it from ordinary jitter — is that the offset is a static, per-client phase set once and kept, not fresh randomness sprinkled on each event. It doesn't perturb individual firings; it structurally decorrelates a periodic schedule so the population stops behaving like one clocked object.
Example¶
A vendor ships 50,000 smart thermostats, each fetching a schedule update every 15 minutes. Out of the box they align to the wall clock — :00, :15, :30, :45 — so the config server sees roughly 50,000 requests inside a two-second window four times an hour and near silence in between. A firmware push that reboots them together only makes it worse: they come back up in lockstep and align even harder.
The fix costs nothing at the server. On first boot each device derives an offset from a hash of its own device ID — deterministic, unique, and stable across reboots — and polls at 15-minute intervals plus that offset. Device arrivals now spread evenly across the whole 15 minutes; the server sees a near-constant stream of roughly 55 requests a second instead of a wall of 50,000 every quarter hour. No coordination, no server-side state, no round-trip: every device decorrelates itself, and the aggregate flattens further the more devices there are. The synchronized schedule that used to hammer the server four times an hour simply stops existing.
How it works¶
- Assign a phase offset once. Each client draws an offset in
[0, period)— randomly, or as a hash of a stable client key so the offset survives restarts and can be reproduced for debugging. - Fire at interval-plus-offset, and keep the offset. The persistence is the point: a fixed offset holds the decorrelation for every future cycle, not just the first.
- Compute locally. No coordinator and no server round-trip; dispersion is a client-side arithmetic, and it improves statistically as the population grows.
- Re-draw only on change. Leave the offset fixed; re-drawing it every cycle would turn this into per-event jitter — a different mechanism with different guarantees.
Tuning parameters¶
- Offset range — usually the full period. A narrower range spreads less but keeps each poll nearer its nominal time, which matters when freshness is phase-sensitive.
- Random vs. hashed offset — pure random is simplest but resets on reinstall; a hash of a stable client id survives restarts and is reproducible. Hashing is precisely what stops a fleet-wide reboot from re-synchronizing everyone.
- Re-draw policy — fixed-for-life vs. re-randomize on config or membership change. Re-drawing too eagerly drifts toward per-event jitter.
- Uniformity target — how flat the arrival histogram actually needs to be; drives how wide the range and how uniform the draw must be.
When it helps, and when it misleads¶
Its strength is that it is nearly free, entirely stateless, and it removes the structural cause of a periodic herd — phase alignment — rather than mopping up the spike after the fact. The more clients there are, the smoother the aggregate becomes.
It helps only when the herd is caused by phase alignment of a periodic schedule. It does nothing for a one-off synchronized event — a fleet rebooting together, an outage-recovery reconnect — where the cue is a single shared moment, not a repeating tick; those need backoff or cohorting instead. The subtle trap is a seed that isn't actually unique: offsets drawn from a default config value, or from a cloned VM image carrying the same seed, leave the whole fleet on the same offset — re-synchronized while you believe you dispersed. And adding an offset while leaving a second aligned trigger in place (all clients also refresh on one shared push) just relocates the alignment.[1] The discipline is to seed from a genuinely per-client, stable key, measure the resulting arrival histogram rather than assume it, and hunt for other shared cues before declaring victory.
How it implements the components¶
release_correlation_metric— the mechanism is defined by the quantity it drives down: the phase-correlation of releases. Success is a flat arrival distribution, and that distribution is the metric it targets and should be measured against.dispersion_policy— the offset assignment is the dispersion policy: spread client phases uniformly across the period so arrivals decorrelate.
It spreads the phase of a self-scheduled polling loop; jittering a shared scheduled release signal — a cron trigger, TTL expiry, or heartbeat — and carrying the jitter_budget on that timer is the Jittered Wakeup Timer. It does not add an escalating post-failure delay (Exponential Backoff with Jitter); it sets one steady phase. And it does not gate, cap, or admit arrivals (Token-Bucket Admission Gate, Semaphore-Limited Release); it only decorrelates them at the source.
Related¶
- Instantiates: Synchronized Release Dampening — the source-side decorrelator that stops a periodic schedule from acting like one synchronized object.
- Sibling mechanisms: Jittered Wakeup Timer · Exponential Backoff with Jitter · Cohort-Based Reactivation · Token-Bucket Admission Gate · Lease or Leader Refresh
References¶
[1] The thundering herd problem is the load spike that results when many waiters are released toward one resource at the same instant. Aligned periodic polling is one of its purest causes, which is why standard scheduling guidance warns against pointing every job at the top of the hour. ↩