upvote
He’s still allowing for exactly 60s between executions. He’s saying stagger the startup by a random amount up to 60s. Then we get what we want every 60s, but they’re all just staggered a random amount.
reply
My bad. I misread it. Delaying the start like that does divide the thundering herd peak by 60. The point about c Rand stands.

The other thing to watch out for is you’ve still got 1/60 of the thundering herd at the second level. If the tasks are <1s and you have enough of them (as you probably do at grid scale), then doing it finer grained is warranted like offsetting the timer by a millisecond sleep of 10 * uniform_distribution<int> between 0 and 6000. That then gives you 10ms granularity, distributing the workload by two more orders of magnitude.

reply
I almost wrote 59.999 seconds too, but I figured someone would nitpick that the timing often won't be that accurate or will get coalesced. ;)

I should have said, you almost always want to use the randomly staggered timers on initialization, not just when the exact timer interval matters! It's also important to test electricity or backend outages, which can unintentionally synchronize all the timers.

reply
You have good advice and I missed the “on startup” for the wait.

A common aggregation is about 10ms although most OSes can give you finer granularity accuracy if you ask for it and have permissions. It really depends on how long the task takes and whether there’s any non-uniformity in its processing to make finer granularity helpful or harmful.

Unfortunately some people do read advice like it’s mana from the gods instead of thinking through the implication on their specific problem.

reply