Data Quality: Beginner
What you will be able to do
Pipeline Ran vs Data Is Good
Recognize the gap between operational success and semantic success, and name the failure mode that hides in that gap.
Two Definitions of Success
| Criterion | What It Asks | Who Notices When It Fails |
|---|---|---|
| Operational success | Did the job exit zero, did the orchestrator mark it green | On-call alert fires within minutes |
| Semantic success | Does the output table describe what the world actually contains | A human asks 'why does this number look strange' hours or days later |
| Combined success | Both criteria pass; the pipeline ran and produced trustworthy data | Nobody notices because nothing is wrong |
The gap between these two criteria has a name: silent data corruption. Silent because nothing in the pipeline raises an alarm. Corruption because the data is wrong. The dashboard updates, the model retrains, the report ships, and the world moves on while the data underneath says something untrue.
Concrete Failure Modes That Look Green
| What Happened Upstream | What the Pipeline Did | What the Output Looked Like |
|---|---|---|
| A Kafka partition dropped events for six hours | Read every event that was actually present, succeeded normally | A row count 30 percent below normal that nobody noticed |
| A producer started sending NULL for a column that used to be required | Loaded the column as NULL; no schema check existed | Downstream joins silently lost rows; revenue dashboard dropped 12 percent |
| A dedupe step changed its key by accident | Ran successfully against the new key; output had duplicate orders | Order count doubled; finance reconciled three days later |
| Source database failover lost the last 15 minutes of writes | Pulled what was there, no awareness of the gap | Customer activity dashboard missed a real spike during a marketing push |
- ▸Did the run finish without raising an exception
- ▸Does the output table describe a world that actually existed
- ▸Without the second question, the answer to the first is misleading
- ▸Quality checks are how the second question gets asked in code
Where Trust Comes From
- Operational success means 'green'; semantic failure goes unnoticed
- Consumers discover problems by spotting strange numbers in dashboards
- Trust is fragile; one wrong number triggers retrospective audits
- Failure root cause takes hours to find because nothing was checked
- Green requires both operational success and quality checks passing
- Failures route to alerts within the same run as the failure
- Trust accumulates because correctness has been continuously proved
- Failure root cause is narrowed by which check fired
What a Quality Check Actually Is
Quality checks are not optional infrastructure for a serious pipeline. Pipelines without them are demos that happened to make it to production.
Four Cheap Quality Checks
Apply the four cheap quality checks (row count, null rate, uniqueness, freshness) to a production table.
What Each Check Catches
| Check | Common Cause When It Fails | What Would Have Happened Without It |
|---|---|---|
| Row count below expected | Source dropped events; filter became too restrictive; join lost rows | Dashboard shows artificially low numbers; decisions made on partial data |
| Row count above expected | Deduplication failed; join exploded into a Cartesian product; backfill ran twice | Aggregates double-count; revenue numbers inflated |
| Null rate spike | Producer changed a required field to optional; upstream extract bug | Joins on the column drop rows silently; downstream metrics shift |
| Uniqueness violated | Dedup step missed; primary key composition changed | Counts double; downstream MERGE statements behave unpredictably |
| Freshness behind threshold | Ingestion job stalled; source system outage; partition not closed | Consumers see stale data and make decisions assuming it is current |
Row Count: The Cheapest Check That Earns Its Keep
Null Rate: One Threshold Per Column
Uniqueness: The Primary Key Has To Be Primary
Freshness: The Last Timestamp
- Add the four checks at the same time as the pipeline, not after the first incident
- Keep thresholds simple and tunable; do not over-engineer at the start
- Compute checks from production data, not from synthetic samples
- Skip the cheap checks because more sophisticated ones are planned
- Hardcode magic numbers without explaining the baseline they came from
- Build dashboards of quality metrics that nobody is paid to watch
Quality Checks at Boundaries
Place quality gates at every layer boundary so that failures stay scoped to the layer where they originated.
The Layered Picture
Three gates, one at each boundary. Gate 1 catches ingestion failures. Gate 2 catches transform failures. Gate 3 catches serving failures. Each gate scopes the diagnostic effort to one layer.
Why End-Only Checks Fail
| Where the Check Sits | What It Catches | What It Fails To Catch |
|---|---|---|
| Only at the end (serving layer) | Visible breakage of consumer tables | Bad raw data that was already aggregated; root cause is buried |
| At every layer boundary | Each kind of failure at the layer where it originated | Nothing in scope; the gates fire on the layer they protect |
| Only at the source | Extraction problems; nothing about transform correctness | Logic bugs in transforms; key changes in joins |
What Each Gate Asserts
| Gate | Layer Boundary | Typical Assertions |
|---|---|---|
| Gate 1: Ingestion | Source -> Raw | Row count from source; primary key uniqueness; freshness of latest record |
| Gate 2: Transform | Raw -> Curated | Curated row count proportional to raw; no orphan foreign keys; required columns populated |
| Gate 3: Serving | Curated -> Serving | Aggregates within historical band; primary key still unique after grouping; SLA-relevant timestamps fresh |
Concrete Example: The Same Failure Scoped Three Ways
- ▸Each gate fires on the layer where the failure originated
- ▸Diagnostic cost is proportional to where the failure was caught
- ▸Downstream transforms do not run on broken data, saving compute and confusion
- ▸The failure root cause is named by the gate that fired
What "At The Boundary" Means
- Runs after the pipeline; humans look at it later
- Failure does not stop downstream work
- Becomes background noise; staleness is normal
- No on-call response when checks fail
- Runs in the DAG; downstream depends on it
- Failure halts the next layer immediately
- Failures are events; engineers respond when they fire
- On-call response is part of the runbook
A quality check that does not have authority to stop the pipeline is information, not a control. Information is useful; controls are protective.
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.
Warn vs Block Authorities
Choose between warning and blocking for each quality check based on the consequence of running with bad data.
The Decision Rule
| Failure Severity | Authority | What Happens |
|---|---|---|
| Output would mislead consumers | Block | Pipeline halts; downstream tables stay on the previous run; on-call is paged |
| Output is degraded but usable | Warn | Pipeline completes; consumers receive a freshness or quality annotation; ticket is filed |
| Output is suspicious but plausible | Warn | Pipeline completes; humans review during business hours; no page |
Examples By Authority
- Primary key uniqueness violated; downstream joins are now wrong
- Required column null rate above 5 percent threshold
- Row count below 50 percent of recent baseline
- Schema mismatch on a column the consumer parses
- Row count 80 to 90 percent of recent average; plausibly a quiet day
- Optional column null rate slightly above norm
- Distribution shift on a non-load-bearing dimension
- Freshness slightly behind SLA but within tolerance
What "Block" Actually Means In Practice
What "Warn" Actually Means In Practice
The Cost of Getting It Wrong
- ▸Downstream consumers will make wrong decisions if the data is published
- ▸The failure cannot be fixed by retry and requires human intervention
- ▸The output will need to be reverted if it is allowed to publish
- ▸The failure indicates a contract violation between producer and consumer
- ▸The data is degraded but still usable for the most common consumer use cases
- ▸The anomaly is plausible (a holiday, a marketing event, a known upstream change)
- ▸The failure is informative for trend analysis but not actionable in the moment
- ▸Halting would cause more disruption than the bad data itself
First Quality Gate: Row Count
Build a complete first quality gate as a SQL assertion wired into a DAG, halting downstream when the assertion fails.
Step 1: Pick the Table and the Assertion
Step 2: Write the SQL
Step 3: Wire the Gate Into the DAG
Step 4: What Happens When the Gate Fires
Step 5: Iterate
| Iteration | Change | Reason |
|---|---|---|
| 1 | Add the row count gate as written | Establishes the floor of quality protection |
| 2 | Add a null rate gate on customer_id, order_amount | Catches producer changes that load-bearing columns started arriving NULL |
| 3 | Add a uniqueness gate on order_id | Catches dedup failures and join explosions |
| 4 | Add a freshness gate on event_timestamp | Catches ingestion stalls before they become row count problems |
| 5 | Tune thresholds against three months of historical data | Reduces false positives; raises confidence in real failures |
The Whole Picture
- Express assertions in SQL where possible; the warehouse is already running the query
- Keep the gate's output a single row with a clear pass or fail value
- Wire the gate as a DAG task that downstream depends on
- Compute the assertion in Python when SQL would do; doubles the surface area
- Skip the historical baseline; magic numbers age badly
- Let the gate share a task with the transform; failures must be distinguishable
> A startup data team has just shipped its first end-to-end pipeline: Postgres orders extracted to S3, transformed in Snowflake into mart.daily_orders, and read by a Looker dashboard for the leadership team. The CEO begins making weekly decisions from the dashboard. The data engineer is asked to make sure the dashboard is right and to make sure the team will be notified when it is not.
A pipeline that ran is not the same as a pipeline that produced correct data
- Category
- Pipeline Architecture
- Difficulty
- beginner
- Duration
- 25 minutes
- Challenges
- 0 hands-on challenges
Topics covered: Pipeline Ran vs Data Is Good, Four Cheap Quality Checks, Quality Checks at Boundaries, Warn vs Block Authorities, First Quality Gate: Row Count
Lesson Sections
- Pipeline Ran vs Data Is Good (concepts: paDataQuality)
Pipelines have two distinct success criteria. One criterion is operational: did the code execute, did the writes commit, did the orchestrator mark the run green. The other criterion is semantic: does the data the pipeline produced actually describe the world correctly. Operational success is necessary but not sufficient for semantic success. The most expensive production incidents in mature data organizations are the ones where operational success and semantic failure coexist, because nobody is
- Four Cheap Quality Checks (concepts: paDataQuality)
Quality engineering has a 90/10 rule. Roughly ninety percent of silent failures are caught by ten percent of the possible checks. The four cheap checks below cover that ninety percent. They run in seconds, they need only basic SQL, and they catch the most common production incidents. The point of starting with these four is that any of them is better than none, and arguments about more sophisticated checks are arguments about edge cases until the basics are in place. The four checks are also the
- Quality Checks at Boundaries (concepts: paDataQuality)
A common mistake in pipeline design is to place all quality checks at the end. The reasoning is that final checks protect the consumer-facing table, which is the part the world sees. The reasoning is incomplete. By the time a problem shows up at the end, several intermediate transforms have already run on bad data. The diagnostic cost climbs because the failure has to be traced back through every transform between the source and the gate. Checks at every layer boundary keep the failure scoped to
- Warn vs Block Authorities (concepts: paDataQuality)
Not every quality check should stop the pipeline. Some failures are catastrophic and demand a halt; others are advisory and demand a notification. Treating every check as a blocker creates an over-protective pipeline that halts on minor anomalies and wakes engineers up at 3am for problems that could have waited. Treating every check as a warning creates a pipeline that ignores its own alarms. The classification is per-check, not per-pipeline, and the rule is simple: block when running is worse t
- First Quality Gate: Row Count (concepts: paDataQuality)
Concepts become useful when applied. The exercise here builds a complete first quality gate: a SQL assertion that the row count for a daily order summary table falls within an expected range. The gate is implemented as a SQL query, the query is run by the orchestrator after the transform finishes, and the gate halts the DAG when the assertion fails. The result is a working quality gate in fewer than thirty lines of code. The exercise is deliberately small. Small gates ship; large gates linger in