Data pipelines don't fail at 3am.
They fail six months before that.
The 3am page is the symptom. The real failure was a decision made six months earlier. How to catch data debt before it wakes someone up.
The pager goes off at 3am and it feels, in the moment, like the pipeline just failed. It didn't, not really. So when did it actually fail? By the time an alert fires, the real failure is usually months old, a shortcut taken under deadline pressure, a test that was never written, a dependency nobody was formally responsible for. The incident is just the day it finally became visible.
01 · Incidents are lagging indicators, not the story itself
This is the reframe that changes how you spend your engineering time: by the time you're paged, the decision that caused the failure is long past, and no amount of incident-response skill fixes that decision retroactively. Treating incidents as the whole story means you only ever get good at responding to symptoms. The actual leverage is upstream, in the ordinary daylight choices that quietly accrue risk long before anything breaks.
$ postmortem trace-origin --incident=inc-4471page fired ............... 2026-06-14 03:07 UTCroot cause committed ...... 2026-01-09gap between cause and page 156 daysroot cause: retry logic added under deadline,never covered by a test, owner since left the team# the 3am page didn't create this problem. it just found it.
“Nobody gets paged the day a shortcut is taken. They get paged the day the shortcut finally runs out of luck.”
02 · What data debt actually looks like, specifically
It rarely announces itself as debt. It looks like a reasonable decision made under a reasonable deadline: a retry added without a test because the fix worked and there wasn't time to also write coverage for it, a transform whose owner moved teams and was never formally replaced, an alert threshold set once at launch and never revisited as volume grew tenfold, a piece of undocumented tribal knowledge that lived entirely in one engineer's head and left the company when they did.
None of those four things will show up in a code review as a problem. Each one is completely invisible until the exact conditions arrive that expose it, which is why they can sit quietly for months.
03 · The audit that catches it while it's still boring
The fix isn't a heroic monitoring push. It's a quarterly review, unglamorous by design, that asks a small number of pointed questions about every pipeline that matters:
- 01Does every critical pipeline have a named owner, right now, not six months ago? Ownership decays as people change teams. An audit that doesn't check this quarterly will trust a name that's already wrong.
- 02Are the transforms that matter actually covered by a test? Not the pipeline as a whole. The specific transformation logic where a silent error would be expensive.
- 03Were alert thresholds set for current volume, or launch-day volume? A threshold that made sense at one-tenth the current load is either firing constantly or never firing at all. Neither is useful.
- 04Is anything about this pipeline only known by one person? If the answer is yes, that's a debt with a specific, urgent expiration date: whenever that person is unavailable.
// the incident above traced back 156 days. that's typical, not extreme. in our experience the median gap between a root cause and the page it eventually causes is measured in months, not days.
04 · The trade is almost always worth it
Ownership, tests, sane alert thresholds, and documentation are boring precisely because they work, silently, by converting a future 3am page into an ordinary daytime ticket that gets fixed on a Tuesday afternoon by someone who was already awake. That trade, a little tedium now for no emergency six months from now, is one of the very few trades in engineering that is almost never a bad one. The daylight work doesn't feel urgent. That's exactly why it's the work most worth doing before you're forced to.
$ end of file · written by flux/dk · 2026-04-06