Drift Detection — Covariate Drift Cost a Fraud Model $2M
Fraud model accuracy fell from 92% to 67% due to covariate drift.
20+ years shipping production ML systems and the infrastructure behind them. Drawn from code that ran under real load.
- ✓Deep production experience
- ✓Understanding of internals and trade-offs
- ✓Experience debugging complex systems
- Model monitoring tracks prediction quality and data distributions over time
- Drift detection uses statistical tests like PSI, KL divergence, and KS test
- Covariate drift = input distribution changes; concept drift = label relationship changes
- PSI > 0.25 typically indicates significant drift in production
- Production insight: most drift alert fatigue comes from testing on too-small windows
- Biggest mistake: treating drift detection as a binary yes/no instead of a severity scale
Imagine you trained a spam filter in 2020, and it worked perfectly. But by 2023, spammers started writing emails that sound like friendly messages — 'Hey buddy, check out this crypto opportunity!' Your filter never saw that style of spam, so it stops catching it. Your model didn't break. The world changed around it. Model monitoring is the alarm system that notices the world has changed. Drift detection is the tool that figures out exactly what changed and how badly.
Every ML model has an expiry date — you just don't know when it is. The moment you deploy a model to production, the clock starts ticking. Real-world data is a living thing: customer behaviour shifts, sensor calibrations drift, economic conditions flip, and language evolves. A model trained on yesterday's data makes yesterday's decisions, and in fast-moving domains that gap kills business value silently and expensively. Unlike a crashed server, a drifting model doesn't throw an error. It just quietly becomes wrong.
The core problem is that ML models are frozen snapshots of a world that keeps moving. Traditional software has deterministic logic you can test; a model's 'logic' is baked into millions of learned parameters that have no automatic self-correction mechanism. When the statistical relationship between your input features and your target label changes, the model has no way of knowing. It will keep producing confident predictions that are increasingly divorced from reality — and your monitoring stack needs to catch that before your users or your business does.
By the end of this article you'll be able to implement a production-grade monitoring pipeline that detects covariate drift, concept drift, and prediction drift using PSI, KL divergence, and the Kolmogorov-Smirnov test. You'll understand which detector to reach for in which situation, the statistical subtleties that trip up even experienced engineers, and how to wire all of it into an alerting workflow that won't wake you up for false positives at 3 a.m.
What Is Model Monitoring and Drift Detection?
Model monitoring is the practice of continuously observing a deployed ML model's performance and input data. Drift detection identifies when the statistical properties of the data or the relationship between inputs and outputs change from the training baseline. Without monitoring, you're flying blind: your model could be making decisions based on patterns that no longer exist.
- Covariate drift: the distribution of input features changes (e.g., user age shifts from 25–35 to 35–45)
- Concept drift: the relationship between features and target changes (e.g., what was considered 'fraud' looks different today)
- Prediction drift: the distribution of model outputs shifts (can signal concept drift even without labels)
In production, you need to detect all three. Each requires a different statistical test and a different response.
- Covariate drift = the water level changed (input distributions)
- Concept drift = the river changed course (relationship changed)
- Prediction drift = the bridge (model) is swaying (outputs shifted)
- You need different tools for each: PSI for water level, KS for course change
Statistical Tests: PSI, KL Divergence, and Kolmogorov-Smirnov
Three tests dominate production drift detection:
- Population Stability Index (PSI): Measures how much a variable's distribution has shifted between two samples. Formula: sum((actual_prop_i - expected_prop_i) * ln(actual_prop_i / expected_prop_i)). PSI < 0.1 = no shift, 0.1–0.25 = minor, > 0.25 = significant.
- KL Divergence: Measures the information lost when using expected distribution to approximate actual. Asymmetric — order matters. Use PSI for symmetric stability, KL for asymmetrical change detection.
- Kolmogorov-Smirnov (KS) Test: Non-parametric test comparing two empirical distributions. Returns a statistic (max difference) and a p-value. Works for continuous features. More sensitive than PSI for location shifts.
In practice, use PSI for categorical/binned features, KS for continuous. KL divergence is useful when you care about directionality of change.
Building a Production Monitoring Pipeline
A robust monitoring pipeline has four layers:
- Data collection: Log model inputs and outputs to a time-series store (e.g., Kafka + InfluxDB). Store at least 30 days of raw feature vectors and predictions.
- Drift computation: Run scheduled jobs (e.g., Airflow DAG every 6 hours) that compute PSI, KS, and prediction drift for each feature vs. the training baseline. Store results in a separate metrics table.
- Alerting: Tiered alerts: INFO (PSI 0.1–0.2), WARNING (0.2–0.3), CRITICAL (>0.3). Confirm drift over at least two consecutive windows before paging. Avoid single-day spikes that are just noise.
- Retraining trigger: When drift exceeds threshold and is confirmed, automatically trigger a retraining job with the latest 30 days of production data. Validate on a recent holdout set before deploying.
This architecture separates detection from action — you can tune alerts without affecting retraining logic.