Data Quality: Advanced
What you will be able to do
What Makes A Contract A Contract
| Property | Implicit Agreement | Data Contract |
|---|---|---|
| Form | Tribal knowledge; Slack threads; an outdated wiki page | A versioned file checked into the producer's repo |
| Enforcement | Discovered after a consumer breaks | Checked in CI on every producer change |
| Visibility | Whoever has been around long enough to know | Discoverable by every consumer through a registry or catalog |
| Versioning | Implicit; whatever was true the last time someone looked | Semver-style; breaking changes require a new major version |
| Failure mode | Production incident | Failed CI run; producer fixes before merge |
Anatomy Of A Contract
Where The Contract Is Enforced
| Stage | What Is Checked | Failure Means |
|---|---|---|
| Producer pre-commit | Producer code emits events that match the contract schema | Pre-commit hook rejects the change |
| Producer CI | Schema, accepted values, ranges, primary key uniqueness | PR cannot merge; producer fixes the violation |
| Pipeline ingestion gate | Real events conform to the contract at the boundary | Quality gate halts; producer is paged |
| Consumer CI | Consumer code reads the contract version it depends on | Consumer build fails; consumer pins or upgrades |
| Registry validation | Contract version is registered and discoverable | Deploy is blocked until registration succeeds |
What CI Enforcement Looks Like
When Contracts Pay For Themselves
- Producer changes a column type; consumers break in production
- Schema rolls forward without consumer awareness
- Producers and consumers debate root cause during the incident
- Adding a new consumer means archeology to find the actual schema
- Breaking change is rejected at producer CI; never reaches consumers
- Schema evolution follows semver; consumers see only versions they pin to
- Root cause is named by the contract version; debate is short
- New consumers read the contract registry and integrate without archeology
What Contracts Cannot Do Alone
- ▸Producers declare contracts before consumers integrate, not after
- ▸Schema evolution follows a documented semver-like policy
- ▸CI rejects breaking changes; production gates rarely have to
- ▸Consumer code declares contract dependencies as explicit pins
- ▸A registry exists where any team can discover what contracts are available
- Version contracts with semver; additive minor, breaking major, fixed-bug patch
- Enforce contracts in producer CI; production gates are the second line of defense
- Publish contracts to a registry that consumers can discover programmatically
- Treat contracts as documentation; without enforcement they accumulate as fiction
- Allow breaking changes in minor versions; consumers will silently break
- Couple the contract format to one tool; contracts outlast any tool decision
The Five Pillars
Pillars As A Diagnostic Framework
| Symptom | First Pillar To Check | Why |
|---|---|---|
| Dashboard shows last week's data on Monday morning | Freshness | Most likely an ingestion stall; rules in or out the simplest cause |
| Revenue dropped 15 percent overnight | Volume | Sudden numeric drops are usually missing rows, not changed values |
| Average order amount is up but row count is steady | Distribution | Aggregate change without row count change implies value shift |
| Pipeline succeeded but downstream join produces nulls | Schema | Type or nullability mismatch is the typical cause of post-success join failures |
| Two consumers see different numbers from the same source | Lineage | Different consumers may read different downstream tables; lineage exposes the divergence |
A pillar is a category. A check is a specific assertion within a pillar. The pillar 'distribution' contains many checks: mean shift, stddev shift, p99 shift, category mix shift, cardinality shift. The framework value of pillars is in coverage, not in implementation. A program that has a hundred checks within four pillars and zero checks in the fifth is a program with a known blind spot.
Lineage: The Pillar Most Programs Skip
When To Adopt Each Pillar
| Maturity Stage | Pillars In Place | What The Team Can Answer |
|---|---|---|
| Stage 1: Cheap checks | Volume, freshness | Did the right amount of data arrive on time |
| Stage 2: Suite | Volume, freshness, schema, distribution | Is the data structurally and statistically as expected |
| Stage 3: Observable | All five pillars including lineage | What changed, why, and who is affected |
| Stage 4: Contract-enforced | All five pillars plus contracts in CI | Same as Stage 3, but most failures cannot ship |
- Incident response starts with 'who owns this column'
- Change reviews miss downstream consumers
- Deprecation requires manual canvassing
- Two consumers compute conflicting numbers; cause is hidden
- Incident response starts with the lineage graph; ownership is metadata
- Change reviews automatically surface affected consumers
- Deprecation walks the graph and notifies every downstream
- Conflicting numbers are explained by divergent transforms in the graph
The pillars are descriptive, not prescriptive. A program with twenty schema checks and zero distribution checks is not 'four-fifths observable'; it is observable on schema and blind on distribution. Coverage is binary per pillar.
The Two SLAs
| Property | Operational SLA | Quality SLA |
|---|---|---|
| Question answered | Did the data arrive on time | Was the data correct |
| Typical statement | Pipeline finishes by 6am every day | Row count within 50 to 200 percent of baseline; null rate below 1 percent |
| Failure mode | Late or missing run | Wrong numbers in a successfully-completed run |
| Detected by | Orchestrator monitoring; missed schedule alerts | Quality gates inside the pipeline |
| Consumer impact | Dashboard or model shows yesterday's data | Dashboard or model shows wrong data |
Why Conflating Them Hurts
Stating Both Explicitly
What The Combined SLA Actually Costs
| Operational | Quality | Combined (Best Case) |
|---|---|---|
| 99.0% | 99.0% | 98.0% |
| 99.5% | 99.5% | 99.0% |
| 99.9% | 99.9% | 99.8% |
| 99.99% | 99.99% | 99.98% |
- Warm pools and pre-provisioned compute
- Retry budgets with exponential backoff
- Redundant orchestrator instances
- Critical-path identification and short-circuiting
- Coverage of all five pillars at every layer boundary
- Threshold tuning against historical data
- Contracts in CI to prevent shape failures
- Lineage to shorten incident response
- ▸Stripe payment events: operational tight (seconds); quality must dominate (no double-charges)
- ▸Daily marketing dashboard: operational moderate (by 9am); quality moderate (refile on error)
- ▸Monthly finance close: operational loose (any time within close window); quality near-perfect
- ▸ML feature store: operational tight (model retraining schedule); quality tight (drift breaks predictions)
- State operational and quality SLAs as separate commitments in the contract
- Compute the combined SLA explicitly; do not promise the geometric impossible
- Report all three (operational, quality, combined) on the producer status page
- Treat 'the pipeline is up' as the only SLA; up-but-wrong is its own failure mode
- Promise high quality SLA targets without a five-pillar suite to back them
- Allow operational improvements to mask quality regression; budget for both
Quality checks live at boundaries: validate on the way in (schema, nulls) and on the way out (row counts, totals). A failing gate stops bad data before it reaches the warehouse.
Alert Fatigue Is A Quality Failure
| Symptom | Underlying Cause | Consequence |
|---|---|---|
| On-call ignores quality pages | Most pages are not actionable; threshold is too tight | Real failures missed; consumer trust degrades |
| Quality dashboard shows constant red | Visualizing every check as critical | The dashboard becomes wallpaper; nobody looks at it |
| Page rate higher than incident rate | False positives outnumber real signal | Engineers escalate to suppress checks; coverage shrinks |
| Engineers create silent alert filters | The system has not been tuned; humans are filtering instead | Filtering becomes tribal knowledge; new on-call doesn't have it |
What 'Tuned' Looks Like
| Quality SLA Target | Implied Page Rate | Threshold Tightness |
|---|---|---|
| 99.9% (one bad day per quarter) | About one page per quarter per check | Loose; only large shifts fire |
| 99.5% (one bad day per month) | About one page per month per check | Moderate; large and persistent shifts fire |
| 99.0% (one bad day per ten days) | About three pages per month per check | Tighter; small persistent shifts fire |
| 95.0% (one bad day per twenty) | Many pages per month per check | Tight; check is approaching alert fatigue |
- Reviewed during business hours
- Tolerates noise; signal extracted by humans during review
- Z-score thresholds in the 2 to 3 range
- Includes plausible day-of-week and seasonal anomalies
- Pages on-call regardless of time of day
- Strict signal-to-noise ratio; tuned to fire rarely
- Z-score thresholds in the 4 to 6 range
- Excludes anomalies that historical review classified as benign
- ▸Engineers create Slack mute rules for specific quality alerts
- ▸On-call routinely acknowledges pages with 'expected; ignoring'
- ▸The same check fires on the same day of the week every week
- ▸New on-call rotations report being overwhelmed by quality alerts
- ▸A real incident is missed because the page was indistinguishable from noise
- Tune every threshold against at least 90 days of historical data before turning it on
- Use two-tier checks: warn loosely and block strictly
- Annotate known anomalies in version control next to the thresholds
- Treat alert volume as a measure of quality coverage; the right measure is incidents caught
- Tighten thresholds reactively after an incident; tighten as a deliberate review
- Allow ad-hoc suppression rules to outlive their original cause
The Starting State
- ▸Producer is a four-year-old Kafka topic with no formal schema; events are JSON
- ▸Three named consumers: leadership dashboard, churn model, billing aggregator
- ▸Unknown number of analyst queries reading from the curated layer
- ▸No quality gates; one wrong-number incident every six to eight weeks
- ▸Schema has drifted: producers have added and renamed fields without coordination
| Change | Version | Type | Consumer Action |
|---|---|---|---|
| Whitelist accepted_values for event_type | 1.1.0 | Backward-compatible (additive guarantee) | None; consumers can adopt the tighter contract or stay on 1.0 |
| Tighten customer_id null rate to <= 1 percent | 1.2.0 | Backward-compatible (tighter guarantee) | None; consumers benefit |
| Rename ts to event_timestamp; strict ISO-8601 | 2.0.0 | Breaking | Pin to 1.x or migrate within 90 days |
| Rename amount to amount_usd; strict decimal | 2.0.0 | Breaking | Pin to 1.x or migrate within 90 days |
| Drop legacy event_types (page_view, click, error) | 3.0.0 | Breaking | Pin to 2.x or migrate within 180 days |
- Wrong-number incident every six to eight weeks
- Three named consumers; unknown analyst surface
- Schema drifts continuously; producers add fields without notice
- Quality is best-effort; no SLA possible
- Rolling back a producer change requires consumer-by-consumer triage
- Wrong-number incidents are rare; most are caught in CI
- Every consumer is registered; lineage covers analyst queries
- Schema evolves through versioned changes with notice
- Operational and quality SLAs are stated and tracked
- Producer can roll back any version because all consumers are pinned
- ▸Document the legacy contract as it actually is, not as the team wishes
- ▸Inventory every consumer; surprise consumers cause migration failures
- ▸Add gates in observation-only mode and tune against the observed data
- ▸Plan cleanups as versioned changes; backward-compatible as minor, breaking as major
- ▸Migrate consumers behind versions on their own schedule within the notice window
- ▸Flip gates to enforcing only after the migration is complete
- Treat the first contract as a documentation of reality, not aspiration
- Use semver explicitly; minor for additive, major for breaking, with notice
- Maintain old and new versions in parallel during the migration window
- Cut over consumers unilaterally; the rollout is a negotiation, not a mandate
- Skip observation mode; thresholds need real data before they can be enforced
- Treat the rollout as one project; treat each version bump as its own change
Contracts and quality become a system only when the producer can roll back any version because every consumer is pinned. The concise statement of the rollout principle: a legacy rollout earns its trust by treating consumers as parties to a negotiation, not as inventory to be migrated, structured by versions and notice periods. The trust accumulates over the months in which no consumer is broken by surprise.
> A staff data engineer joins a public-company data platform team. The platform has every quality check the intermediate tier prescribes. On-call rotations are burning out from alert fatigue. Half of incidents are caught by gates and half are still discovered by consumers asking 'why does this number look wrong'. The engineer is asked to turn the quality program into something the team trusts and the consumers can rely on.
Contracts make quality enforceable; observability makes it diagnosable; tuning makes it trusted
- Category
- Pipeline Architecture
- Difficulty
- advanced
- Duration
- 38 minutes
- Challenges
- 11 hands-on challenges
Topics covered: Data Contracts and CI Enforcement, Five Pillars of Observability, Quality SLAs vs Ops SLAs, Tuning Thresholds vs History, Contracts on a Legacy Pipeline
Lesson Sections
- Data Contracts and CI Enforcement (concepts: paSchemaEvolution)
Lesson 1's advanced tier introduced the pipeline-as-product framing: a pipeline has a contract that names producer, consumer, schema, freshness SLA, quality SLA, backfill policy, and deprecation policy. This section turns that framing into a working mechanism. A data contract is the executable form of the commitment. The producer commits to a shape and a set of guarantees; the consumer relies on them; the contract is checked in CI on every change so violations cannot ship. Without enforcement, c
- Five Pillars of Observability (concepts: paDataQuality)
Barr Moses and the Monte Carlo Data team named the five pillars of data observability: freshness, distribution, volume, schema, and lineage. The naming has caught on widely enough that conversations about quality use it as shorthand. The pillars are useful because they are not a checklist; they are a diagnostic framework. When something is wrong with the data, the pillar that detected the symptom narrows the search for the cause. When designing a quality program, the pillars name the gaps that h
- Quality SLAs vs Ops SLAs (concepts: paDataQuality)
An SLA states a commitment. The pipeline-as-product framing from Lesson 1 introduced two SLAs as elements of the contract: freshness SLA and quality SLA. They are commonly conflated. They are different commitments to different things, with different consequences when they fail. A pipeline that meets its operational SLA can fail its quality SLA in green. A pipeline that meets its quality SLA can miss its operational SLA without affecting correctness. The producer who treats both as one number end
- Tuning Thresholds vs History (concepts: paDataQuality)
A quality system that fires too often gets ignored. The mechanism is simple. On-call engineers receive twenty pages a week. Three of them are real. The remaining seventeen train the engineer to acknowledge alerts without reading them carefully. The next real page lands in the same Slack channel as a false one and is missed. The pipeline that the team thought was protected is, in operational terms, unprotected, because the protection mechanism has been desensitized by its own noise. The fix is no
- Contracts on a Legacy Pipeline (concepts: paSchemaEvolution)
Greenfield contracts are easy. Contracts on a legacy pipeline that has run for four years and has dozens of unknown consumers are hard. The mistake most teams make is treating the rollout as a one-shot migration: write the contract, declare the producer compliant, declare consumers responsible for catching up. The mistake produces breakage and erodes the credibility of the contract program. The disciplined rollout treats existing consumer behavior as the starting contract, evolves toward the des