Skip to content
Anil Thapa
Work

Data quality and reliability as an operating discipline

Earning trust in the numbers

A plausible wrong number can change how people use an entire platform. Prioritizing critical data, exposing uncertainty, and rebuilding confidence through a response people can inspect.

TestingFreshness monitoringLineageAlerting

What this is about

  • Trust can fall quickly; recovery needs visible evidence of a better process
  • Cover the numbers your most skeptical stakeholder uses, first
  • Make the impact, response, and follow-through visible

A synthesis of recurring reliability work. The outcome section gives evaluation criteria; Uber’s reported detection result is an external example.

Situation

Every other pattern on this page assumes something that is rarely true: that when the platform produces a number, people believe it.

Trust is the actual product of a data function. Not dashboards, not pipelines, not models: the willingness of somebody making a decision to use your number instead of their own. And it behaves in a way that is deeply counterintuitive to engineers, because it is not proportional to correctness.

Trust can fall much faster than it recovers. A visible error can make people question numbers well beyond the affected dataset. Some start checking every answer manually; others quietly return to their own reports. Neither response is inevitable or permanent. The severity of the error, the decision it affected, and the team’s response all matter.

Recovery needs evidence people can inspect: a clear account of the failure, controls that address it, and a sustained record of useful, reliable answers.

A pipeline that fails loudly gives the team a chance to intervene before consumers use the data, although an outage can still cause serious harm. A pipeline that silently produces a plausible wrong number can affect a decision and cast doubt on other outputs. Silent errors need deliberate attention because availability monitoring alone will not find them.

What makes this hard is that the failure is usually invisible from inside the team. Nobody reports a number that looks reasonable. It gets used, a decision gets made, and the discovery comes weeks later during a reconciliation, by which point the damage is not one wrong figure but a general suspicion that has no specific target and therefore cannot be specifically answered.

Constraint

  • Coverage and alert routing are different decisions. A platform of any size has thousands of assertions worth making. Routing every failure to the same alert channel produces noise. Broad automated checks can still be useful if severity, ownership, and routing are explicit.
  • The people who need to trust the numbers are not the people who can evaluate the tests. An executive cannot assess your coverage. They assess whether the number was right last time it mattered.
  • Quality work is invisible when it succeeds. There is no recognition for the incident that did not happen, which makes this chronically under-resourced relative to its importance.
  • Upstream systems change without telling you. Failures can originate outside the data platform: an application migration, a vendor schema change, a well-intentioned fix to a source system.

The first constraint is the one that shapes the design. Quality is not a coverage problem to be maximized; it is a prioritization problem, and treating it as coverage is how teams end up with ten thousand tests and no trust.

Decision

Prioritize by blast radius, not by coverage. The question is not “what could be wrong” but “what would be catastrophic if it were wrong, and who would find out how.”

Start with the numbers your most skeptical stakeholder uses

Identify the handful of metrics that appear in the decisions that matter, the board pack, the weekly leadership review, the figures finance defends externally and give those explicit service expectations and a tested response before extending deeper checks to the long tail. Include operational decisions with material consequences even when they have little executive visibility.

Agreeing the critical set with consumers makes the prioritization defensible to the people carrying the business risk.

Distinguish the four failure modes and test for each

A useful review covers four failure modes. Structural correctness checks alone leave gaps in the other three:

  • Freshness. The number is correct and eighteen hours stale, and the dashboard does not say so. A freshness target makes that limitation visible and testable.
  • Completeness. Some records arrived and some did not. Partial success is far more dangerous than total failure because nothing looks broken. Row-count changes are a useful signal, but source-to-target checks are needed where a stable total can hide missing and duplicated records.
  • Correctness. The classic case: a join that duplicates, a filter that drops, a definition that drifted from what the business means. Uniqueness, not-null, relationship and accepted-value tests catch structural defects. Known business examples and reconciliation against an authoritative source test the meaning.
  • Consistency. Two systems disagree about the same fact, and both are internally valid. This is the one that surfaces in meetings rather than in monitoring, and reconciliation checks and agreed scopes help distinguish an error from a legitimate difference in definition.

Make freshness and lineage visible to consumers

The single highest-leverage thing available, and it is not a test: put the as-of time on the dashboard, and make lineage traceable without asking anyone.

A visible timestamp helps the consumer assess whether the number is usable. It does not excuse missing an agreed freshness target. A stale number that looks current is. Similarly, when somebody questions a figure, the ability to trace it to source in minutes converts a credibility incident into a technical conversation. Without lineage, every question becomes a referendum on the team.

Instrument the sources you do not control

Include monitoring at the source boundary: schema change detection on ingestion, volume anomaly detection against expected ranges, and explicit contract checks on the handful of fields that matter most. Finding out from your own monitoring that an application team changed a column is a normal Tuesday. Finding out from an executive is an incident.

Run incidents like incidents

This is where trust is actually won or lost, and most data teams handle it badly by treating a wrong number as an engineering bug rather than a communications event.

What works:

  1. Announce it before it is found. Proactive disclosure of a wrong number costs a fraction of what discovery costs. This is genuinely difficult and it is the whole thing.
  2. State the blast radius plainly. What was wrong, since when, which decisions may have used it. Vagueness here reads as concealment.
  3. Say what changes so it does not recur, and then actually do it. A postmortem with no resulting test is theatre that people notice.
  4. Do not over-apologize. Executives deal in operational failure constantly. A clear, unemotional account of what happened and what changed is received far better than contrition, which reads as a team that is rattled.

Finding and reporting failures promptly can preserve confidence. Repeated incidents still need prevention and follow-through; disclosure alone does not make an unreliable service trustworthy.

The tradeoff I accepted

I chose deep coverage on a narrow set of critical numbers over broad coverage across the platform, and the long tail genuinely suffered.

The consequence is real and I would not soften it: less-critical datasets ran with thin testing, and some of them were wrong for a while before anyone noticed. Analysts working in those areas occasionally found problems the platform should have caught. That is a cost paid by real people doing real work, and it is a direct result of my prioritization.

I accepted it because the alternative, spreading the same limited effort evenly, can leave critical decisions under-protected. Equal coverage does not imply equal failure probability or equal consequences. I would retain cheap baseline checks broadly and allocate deeper validation according to impact, including operational uses that never appear in a board pack.

Other honest costs:

  • Alert tuning is permanent, unglamorous work. Thresholds drift, seasonality breaks naive anomaly detection, and an alerting channel degrades into noise within a quarter without active maintenance. Nobody wants this job and it has to be somebody’s.
  • Some of the discipline reads as bureaucracy. Requiring tests on a model someone wants to ship today is a real tax on velocity, and the people paying it do not experience the incident it prevented.
  • Proactive disclosure is culturally expensive at first. The first few times a team announces its own error, it feels like volunteering for criticism. It only pays off once enough instances have accumulated for people to recognize the pattern, and that takes longer than it feels like it should.

Outcome

The work I can point to is an operating foundation: named data ownership, shared metric definitions, lineage, cataloging, and observability, alongside review and deployment standards. That foundation supported both reporting and natural-language self-service. It made context and responsibility part of the platform rather than something each consumer had to reconstruct privately.

That establishes what was put in place, not a personal incident-detection rate. I would evaluate its continuing effectiveness with the measures below.

One useful signal is who finds the problem first. Read it alongside severity, time to recovery, recurrence, and effects on decisions.

Early detection gives the team a chance to limit harm. It is not sufficient on its own: repeated failures, slow recovery, and uncorrected past decisions can erode trust even when the team finds the problem first.

I would evaluate the approach against these observable criteria:

  • Failures are found by monitoring, and the team communicates them before anyone asks.
  • Questions about a number are answered by tracing lineage in minutes, not by launching an investigation.
  • Stale data is visibly labelled as stale, so nobody is ever misled by a number that was merely old.
  • The conversation shifts from “is this right” to “what does this mean,” which is the same marker of success as every other pattern on this page and is not a coincidence.

What I’d do differently

Instrument freshness on day one, before building any transformation. It is the cheapest signal available, it catches the most common trust failure, and I have consistently built it later than I should have because it feels like monitoring rather than like progress.

Define the critical metric set with stakeholders rather than for them. I inferred which numbers mattered most from usage. Asking directly, “which figures would embarrass you if they were wrong”, produces a different and better list, and the act of asking does its own work on the relationship.

Write the incident communication template before the incident. Composing a clear disclosure while an incident is live, under pressure, produces worse communication than a template drafted calmly. It takes twenty minutes on a quiet afternoon and it is worth considerably more than that.

Resource the alert maintenance explicitly. I treated tuning as something that would happen alongside other work. It does not. It decays, the channel fills with noise, people stop reading it, and the monitoring becomes decorative several months before anyone notices it has.

Facing a similar decision?

Explore a decision review or mentoring for data managers and first-time heads of data.

Working together

Another decision from practice

One number, two histories

Read it