There’s a category of data bug that’s easy to overlook because it doesn’t announce itself as a bug. The system is running. The data is present. Queries return results. And yet the data is wrong — not because of a calculation error or a schema mismatch, but because it’s old. The process that updates it ran weeks ago and hasn’t run since. What’s in the database is an accurate snapshot of a state that no longer exists.

This is a freshness failure, and it’s structurally different from the kinds of failures most monitoring setups are designed to catch. Error rate monitoring assumes that stale data isn’t silently returned as valid data. Query success monitoring assumes that a successful query means the data was worth querying. Neither assumption holds when the underlying update process is failing silently. The query succeeds; the error rate is zero; the data is three weeks out of date.

Freshness monitoring requires tracking a different property: not whether a process ran, but when the thing it produces was last updated. This often means adding a timestamp to the data itself — a last_updated or valid_until field that records when the data was generated, not when it was queried. The monitoring check then asks: is this value newer than X? If the answer is no, something went wrong upstream, regardless of whether any errors were logged.

The value of a freshness signal comes from specificity. A generic “last updated” timestamp on a table tells you the table has recent writes, which could come from any row. What you usually want is a freshness signal tied to the specific thing that matters: the last time this particular pipeline ran to completion, the last time this particular cache was refreshed, the last time this particular document set was re-indexed. The more specific the freshness check, the smaller the blast radius when something goes wrong — you find out that the document index is stale, not just that the database has been written to recently.

The mental model shift is from “is the process healthy” to “is the output current.” A process can be healthy in every observable way — no crashes, no error logs, no resource spikes — and still be producing stale output. It could be running and failing gracefully, or running on a schedule that’s no longer frequent enough for the data’s rate of change, or not running at all because the scheduler is broken in a way that doesn’t produce errors. The process view misses all of these. The output view catches all of them, because what you’re asking is simpler and more direct: is what’s in here still true?