DEV Community

Cover image for My deploy check waits 60 seconds. My outage alarm waits 5. I measured neither.
FromZeroToShip
FromZeroToShip

Posted on • Originally published at fromzerotoship.com

My deploy check waits 60 seconds. My outage alarm waits 5. I measured neither.

Two numbers from my own systems, side by side.

When I deploy, a check confirms the pages are actually live. It retries three times, twenty seconds apart, so it tolerates up to a minute of "not there yet" before calling anything wrong.

When my monitor decides whether production is down, it waits five seconds and retries once.

The check that guards the more consequential claim is the more impatient one. I did not decide that. I never compared them. Until last week I had never seen those two numbers in the same place, and neither had anything else.

Where the numbers came from

The deploy one has an origin story I'd have told you proudly a week ago.

I shipped nine pages, then checked the URLs immediately instead of trusting the CLI's success message. Four returned 404. Nothing was broken — CDN propagation — and twenty seconds later all nine were 200. A single check at the wrong moment would have told me, with total confidence, that a perfectly good deploy was broken.

So I wrapped it in a retry loop. Three attempts, twenty seconds apart. Problem solved, and it even sounds like engineering.

Here is the part that isn't. I picked twenty because it was the first interval where the false alarms stopped. My sample was about three deploys. I have never recorded how long propagation actually takes. I widened the tolerance until the red went away, and then I wrote about it as if I'd learned something.

Someone in a thread named this before I saw it: a tolerance chosen that way is the same muting I'd been criticizing, relocated inside the assertion where it reads as rigor instead of avoidance.

The test I was given, and the answer I didn't want

In that same thread I speculated that my deploy tolerance was probably leaking into my outage detector through a shared helper. It sounded plausible and I said it like a finding.

The reply was sharper than the guess: that's a falsifier, not evidence. Here's the concrete test — do the two checks consume the same retry policy or threshold configuration? If yes, two different claims have already collapsed into one mechanism.

So I ran it. The answer is no. Nothing is shared.

Which turned out to be worse.

deploy verification   3 attempts × 20s     a shell loop I retype by hand each time
outage monitor        1 retry after 5s     written inline at three call sites in one file
Enter fullscreen mode Exit fullscreen mode

No shared configuration means no leak. It also means nothing versioned, nothing reviewable, nothing anyone could pre-register. A shared helper would at least have put the number somewhere a person could find it and argue with it.

Then I widened the search across the codebase:

Timeout / retry literals found 40+
Distinct values 3s, 5s, 8s, 10s, 12s, 15s, 75s, 90s, 120s, 600s
Written inline at the call site all of them
Derived from a measurement none

Forty-plus numbers, each typed by me at the moment I needed one, each chosen by how it felt, none of them ever compared to another.

Two different ways a constant is wrong

Someone else in these threads drew a line I'd been blurring, and it changed what I think the fix is.

Their system had a signup limit: five accounts per hour per IP. Written when users arrived one at a time from search — a completely sensible number. Then the link went into a group chat, and an entire office behind one NAT would have been locked out after five.

Their earlier examples were constants calibrated to a rhythm that later changed — a reminder window sized for a tournament, then applied to a nine-month league season. That's drift, and drift is catchable: record what was true when you set the number, and the day reality diverges you have something to compare against.

The rate limit isn't that. It wasn't correct-then and stale-now. It encoded an assumption about identity — one IP means roughly one person — and that was never true. Nothing drifted. It had simply never been exercised.

So some constants rot, and some were wrong at birth and merely unexercised. A dated note catches the first kind. Only something adversarial catches the second, and the tell for that family is a key that stands in for identity rather than measuring it.

Mine are mostly the first kind. That doesn't make them better; it makes them the kind I had the tools to catch and didn't.

Three things a threshold needs

Not "pick better numbers." I can't pick better numbers — that's the whole problem.

A birth certificate. When it was set, what the distribution looked like at that moment, and how far it's allowed to drift before something complains:

const CAL_SINCE = '2026-07-27', CAL_BASELINE = 19, CAL_DRIFT = 2;
Enter fullscreen mode Exit fullscreen mode

That's from the one place I already do this. A machine computes the divergence and prints it. Compare that to a comment saying "20s seems fine," which requires me to reread it and be alarmed, and I have demonstrated that I won't.

A rule fixed before the run it judges. This is the correction I'd have missed on my own. Deriving the threshold from measured data still lets me revise until the red disappears — only now with a distribution available to rationalize the revision. The rule has to be versioned and fixed in advance, so that changing it becomes an event with a record rather than a quiet adjustment.

The value, not just the verdict. My deploy check currently emits pass or fail. A deploy that resolves in two seconds and one that takes thirty-nine produce identical output, which means the check is hiding exactly the signal that would tell me it's miscalibrated. A slow deploy should stay visible even when it passes. Until it does, I have no series to derive anything from — which is why I still can't tell you what the right number is.

The tell

Here's what I'd check in your own systems, and it takes about a minute.

Find a timeout or a retry count in your code. Ask where the number came from. If the honest answer is "it stopped failing at that value," it isn't a measurement. It's a preference, and it's currently deciding when you get woken up.

Mine are five seconds and sixty seconds, guarding claims of very different consequence, in the opposite order from what you'd choose on purpose.


This is part of Stolen from the Feed — what a non-developer carries home from dev.to and actually builds. Sister series to From Zero to Ship.

Top comments (0)