Tuning Thresholds vs History
Concepts covered: Data Quality & Validation
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 not to remove checks. The fix is to tune the thresholds against historical data so that the alarm rate is low enough that every alarm is read carefully. The same dynamic appears in security operations centers, in airline cockpits, and in hospital telemetry alarms, and in every domain the conclusion is identical: an alert system has a finite signal-to-noise budget, and exceeding the budget destroys the system's value. Quality engineering has not historically thought of itself as alarm-system design, but it is.
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 |
Threshold tuning runs the proposed assertion against historical data and counts the alerts that would have fired. A threshold that would have fired three hundred times on the last ninety days of data is not a threshold; it is a constant. A threshold that would have fired zero times is not a threshold; it is a non-check. A useful threshold fires somewhere between two and ten times in a ninety-day window, and each firing corresponds to either a real incident or a known anomaly that can be classified as such. The tuning is empirical, not theoretical.
WITH daily_stats AS (
SELECT order_date, AVG(amount_usd) AS daily_mean
FROM fct_orders
WHERE order_date BETWEEN CURRENT_DATE - 90 AND CURRENT_DATE - 1
GROUP BY order_date
),
rolling AS (
SELECT order_date, daily_mean,
AVG(daily_mean) OVER (ORDER BY order_date ROWS BETWEEN 28 PRECEDING AND 1 PRECEDING) AS rolling_mean,
STDDEV(daily_mean) OVER (ORDER BY order_date ROWS BETWEEN 28 PRECEDING AND 1 PRECEDING) AS rolling_sd
FROM daily_stats
)
SELECT order_date, daily_mean, ROUND((daily_mean - rolling_mean) / rolling_sd, 2) AS z_score
FROM rolling
WHERE ABS((daily_mean - rolling_mean) / rolling_sd) >= 3
ORDER BY order_date;The query produces the dates on which a z >= 3 threshold would have fired. The team reviews each date with an analyst: was something real happening, or was the threshold too tight. Tuning continues until the firing rate matches the rate at which the team can credibly investigate every firing without ignoring any of them.
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 |
A practical pattern uses two thresholds per check. A warning threshold fires more often, into a channel where humans review during business hours. A blocking threshold fires rarely, into the on-call rotation. The warning catches plausible-but-suspicious shifts; the blocker catches definite-and-actionable failures. The warning channel is allowed to be noisy because it does not interrupt anyone outside business hours; the blocking channel is held to a strict signal-to-noise ratio because every page interrupts an engineer.
- Warning Channel
- 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
- Blocking Channel
- 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
Many quality false alarms are calendar effects: holidays, end-of-month spikes, marketing campaigns, product launches. A pure z-score against a trailing window catches these as alerts, even though they are predictable. The fix is to enrich the baseline with calendar awareness: same-day-of-week comparisons, holiday flags, campaign annotations. The baseline becomes a model rather than a sliding average. The investment is worth it for high-volume tables where calendar effects produce most of the noise. For low-volume tables, the same investment is over-engineering.
WITH baseline AS (
SELECT EXTRACT(DOW FROM order_date) AS day_of_week,
AVG(daily_count) AS dow_mean,
STDDEV(daily_count) AS dow_sd
FROM fct_orders_daily
WHERE order_date BETWEEN CURRENT_DATE - 90 AND CURRENT_DATE - 1
GROUP BY EXTRACT(DOW FROM order_date)
)
SELECT EXTRACT(DOW FROM CURRENT_DATE) AS dow_today,
(SELECT COUNT(*) FROM fct_orders WHERE order_date = CURRENT_DATE) AS today_count,
ROUND(baseline.dow_mean, 0) AS dow_mean,
ROUND(((SELECT COUNT(*) FROM fct_orders WHERE order_date = CURRENT_DATE) - baseline.dow_mean) / baseline.dow_sd, 2) AS z_score
FROM baseline
WHERE day_of_week = EXTRACT(DOW FROM CURRENT_DATE);Some anomalies are real and not bugs. Black Friday produces a row count spike that the threshold should know about. A planned product launch produces a feature distribution shift that the threshold should know about. Annotating these in advance prevents the threshold from firing on them. The annotation lives next to the threshold definition and is reviewed in the same PR cycle. Without annotations, the team adds suppression rules ad-hoc during the incident, and those rules outlive the event they were created for.
# Calendar annotations consulted by the threshold engine
known_anomalies:
- date: '2026-11-27'
table: fct_orders
metric: row_count
expected_z_shift: '+8 to +15'
reason: 'Black Friday'
- date_range: '2026-12-20 to 2026-12-26'
table: fct_orders
metric: amount_usd_mean
expected_z_shift: '+2 to +5'
reason: 'Holiday gifting; higher AOV'
- date_range: '2026-04-15 to 2026-04-22'
table: fct_customer_events
metric: event_type_signup_pct
expected_z_shift: '+3 to +6'
reason: 'Spring marketing launch'1 to 5% Target firing rate for blocking checks against historical data: Higher rates produce alert fatigue; lower rates indicate a non-check
- Do
- 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
- Avoid
- 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
About this lesson
This section is part of the Data Quality: Advanced lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.