Implementing Pipeline Observability
When to use
- Failures or stale data are discovered by stakeholders, not by your alerts.
- Setting up monitoring, SLAs, or on-call for data pipelines.
- Alerts are too noisy (fatigue) or too quiet (silent failures).
- Do NOT use for one-off incident debugging (use
debugging-data-pipelines).
The four signals to monitor
- Freshness — is data arriving within its SLA? (most incidents are lateness)
- Volume — is row count within the expected range vs a trailing baseline?
- Quality — do the data quality checks pass? (see
implementing-data-quality-checks)
- Run health — job success/failure, duration, and retry rate.
Workflow
- [ ] Define SLAs per critical dataset (freshness + volume)
- [ ] Emit run metrics: status, duration, rows in/out per run
- [ ] Add freshness + volume monitors with baseline-relative thresholds
- [ ] Route alerts to an owner with context and a runbook link
- [ ] Tune thresholds to cut false positives; track MTTD/MTTR
- Set SLAs for datasets that feed decisions ("orders fresh within 3h,
±20% daily volume"). Without an SLA there is nothing to alert against.
- Emit run metrics (status, duration, input/output row counts) to a store you
can query and chart, not just scattered logs.
- Monitor freshness and volume against trailing baselines, not fixed
numbers, so seasonality doesn't trigger noise.
- Make alerts actionable — every alert names the dataset, the breached SLA,
the likely blast radius, and links a runbook. Route to a clear owner.
- Tune — suppress duplicates, group related alerts, and set severities so
people trust the pager.
Patterns
Freshness monitor:
-- Alert when the newest row is older than the SLA.
SELECT DATEDIFF('hour', MAX(ordered_at), CURRENT_TIMESTAMP()) AS hours_stale
FROM fct_orders
HAVING hours_stale > 3;
Volume anomaly vs trailing baseline — compare today's count to the mean of the
prior N days and alert on a large relative deviation, catching partial loads and
duplication that a fixed threshold misses.
Run metrics — record {pipeline, run_id, status, started_at, duration_s, rows_in, rows_out} per run; chart duration and row counts to spot drift before it
becomes an incident. Tools: dbt artifacts, OpenLineage/Marquez, Elementary, Monte
Carlo, or a simple metrics table.
Alert routing — critical → page the owning team with a runbook; warning →
async channel. Deduplicate and group so one upstream failure isn't 50 pages.
Common pitfalls
- Alerting only on job failure — data can be stale or wrong while every job
"succeeds"; monitor freshness/volume/quality too.
- Fixed thresholds on seasonal data — false positives train people to ignore
alerts; use trailing baselines.
- Alerts with no owner or context — nobody acts; include dataset, SLA, impact,
and a runbook.
- Over-alerting — fatigue causes real incidents to be missed; tune severity
and dedupe.
- No metrics history — you can't see gradual regressions (creeping duration,
shrinking volume) without stored run metrics.
- Monitoring everything equally — focus SLAs on datasets that drive decisions.
1---2name: implementing-pipeline-observability3description: Instrument data pipelines with observability — freshness and volume SLAs, run success/latency metrics, data quality monitors, anomaly detection, lineage, and actionable alerting that avoids fatigue. Use when pipelines fail silently, incidents are found by stakeholders instead of alerts, setting up monitoring/SLAs for data, or reducing noisy alerts.4---56# Implementing Pipeline Observability78## When to use910- Failures or stale data are discovered by stakeholders, not by your alerts.11- Setting up monitoring, SLAs, or on-call for data pipelines.12- Alerts are too noisy (fatigue) or too quiet (silent failures).13- Do NOT use for one-off incident debugging (use `debugging-data-pipelines`).1415## The four signals to monitor16171. **Freshness** — is data arriving within its SLA? (most incidents are lateness)182. **Volume** — is row count within the expected range vs a trailing baseline?193. **Quality** — do the data quality checks pass? (see20 `implementing-data-quality-checks`)214. **Run health** — job success/failure, duration, and retry rate.2223## Workflow2425```26- [ ] Define SLAs per critical dataset (freshness + volume)27- [ ] Emit run metrics: status, duration, rows in/out per run28- [ ] Add freshness + volume monitors with baseline-relative thresholds29- [ ] Route alerts to an owner with context and a runbook link30- [ ] Tune thresholds to cut false positives; track MTTD/MTTR31```32331. **Set SLAs** for datasets that feed decisions ("orders fresh within 3h,34 ±20% daily volume"). Without an SLA there is nothing to alert against.352. **Emit run metrics** (status, duration, input/output row counts) to a store you36 can query and chart, not just scattered logs.373. **Monitor freshness and volume** against **trailing baselines**, not fixed38 numbers, so seasonality doesn't trigger noise.394. **Make alerts actionable** — every alert names the dataset, the breached SLA,40 the likely blast radius, and links a runbook. Route to a clear owner.415. **Tune** — suppress duplicates, group related alerts, and set severities so42 people trust the pager.4344## Patterns4546**Freshness monitor:**4748```sql49-- Alert when the newest row is older than the SLA.50SELECT DATEDIFF('hour', MAX(ordered_at), CURRENT_TIMESTAMP()) AS hours_stale51FROM fct_orders52HAVING hours_stale > 3;53```5455**Volume anomaly vs trailing baseline** — compare today's count to the mean of the56prior N days and alert on a large relative deviation, catching partial loads and57duplication that a fixed threshold misses.5859**Run metrics** — record `{pipeline, run_id, status, started_at, duration_s,60rows_in, rows_out}` per run; chart duration and row counts to spot drift before it61becomes an incident. Tools: dbt artifacts, OpenLineage/Marquez, Elementary, Monte62Carlo, or a simple metrics table.6364**Alert routing** — critical → page the owning team with a runbook; warning →65async channel. Deduplicate and group so one upstream failure isn't 50 pages.6667## Common pitfalls6869- **Alerting only on job failure** — data can be stale or wrong while every job70 "succeeds"; monitor freshness/volume/quality too.71- **Fixed thresholds on seasonal data** — false positives train people to ignore72 alerts; use trailing baselines.73- **Alerts with no owner or context** — nobody acts; include dataset, SLA, impact,74 and a runbook.75- **Over-alerting** — fatigue causes real incidents to be missed; tune severity76 and dedupe.77- **No metrics history** — you can't see gradual regressions (creeping duration,78 shrinking volume) without stored run metrics.79- **Monitoring everything equally** — focus SLAs on datasets that drive decisions.