Model Drift Detection: Why Your ML Model Fails Silently
How to detect data drift, concept drift, and prediction drift before your users notice.
Model Drift Detection: Why Your ML Model Fails Silently (And How to Catch It)
Your model was 94% accurate when you deployed it three months ago. Today? You don't know. Because unlike a crashed server, a degrading ML model doesn't throw errors. It just slowly becomes wrong.
This is model drift. Here's how to detect it before your users do.
What Is Model Drift?
Model drift comes in three flavors:
1. Data Drift (Input Drift)
The distribution of your input data changes. Your sentiment model was trained on movie reviews from 2023. Now it's seeing product descriptions in 2026. Same model, different inputs.
Real example: A credit scoring model trained pre-COVID. Post-COVID, income distributions shifted significantly. The model was still evaluating people against 2019 economic baselines.
2. Concept Drift
The relationship between inputs and outputs changes. "Great battery life" meant 5/5 stars in 2020. In 2026, with new battery tech, the bar is higher. The same text now signals different sentiment.
3. Prediction Drift
Your model's output distribution shifts over time. If your classifier went from 70% positive/30% negative to 50/50, something changed — either your inputs, or your model, or reality itself.
How to Detect Drift
Population Stability Index (PSI)
PSI is the most widely used drift metric. It compares the distribution of a feature between two time periods:
PSI = sum over buckets: (actual% - expected%) * ln(actual% / expected%)
Interpretation:
- PSI < 0.1: No significant drift
- PSI 0.1-0.2: Moderate drift — investigate
- PSI > 0.2: Significant drift — take action
Implementation
import numpy as np
def calculate_psi(expected, actual, bins=10):
"""Calculate Population Stability Index between two distributions."""
breakpoints = np.linspace(0, 100, bins + 1)
expected_percents = np.histogram(expected, breakpoints)[0] / len(expected)
actual_percents = np.histogram(actual, breakpoints)[0] / len(actual)
# Avoid division by zero
expected_percents = np.where(expected_percents == 0, 0.0001, expected_percents)
actual_percents = np.where(actual_percents == 0, 0.0001, actual_percents)
psi = np.sum(
(actual_percents - expected_percents) * np.log(actual_percents / expected_percents)
)
return psi
Run this daily on a sample of your inference data. Compare against your training data distribution (the "expected" baseline).
Automated Drift Monitoring with Roptal
Roptal monitors drift across every deployed model:
- Baseline profile captured at deployment time (training data statistics)
- Daily PSI calculation on inference data samples
- Alerts when PSI exceeds 0.2 for any feature
- Dashboard showing drift trends over time
The monitoring is built into the deployment pipeline — no separate setup required.
What to Do When Drift Is Detected
PSI 0.1-0.2: Monitor More Frequently
- Increase sampling rate from daily to hourly
- Check if the drift is accelerating
- Review recent data pipeline changes
- This is often caused by a change in data source, not the model
PSI > 0.2: Take Action
- Investigate first: Check data pipeline, upstream systems, API changes
- Rollback: Switch to previous model version (Roptal keeps last 3 versions warm)
- Retrain: If the drift is genuine (concept drift), update training data and retrain
- Canary deploy: Deploy retrained model as a canary (10% traffic) and compare against current model
PSI > 0.3: Emergency
- Roll back to last known good version immediately
- Investigate root cause before redeploying
- This level of drift usually indicates a broken data pipeline, not gradual concept drift
Beyond PSI: Advanced Drift Detection
For mission-critical models, add these to your drift monitoring:
| Method | What It Detects | Complexity |
|---|---|---|
| PSI | Distribution shift | Low |
| KS Test | Statistical significance of shift | Medium |
| Wasserstein Distance | Magnitude of distribution shift | Medium |
| CUSUM | Detects change points in time series | High |
| Isolation Forest | Detects anomalous individual predictions | High |
The Silent Failure Problem
The scariest thing about model drift: your users notice before you do. A customer complains about incorrect predictions → you investigate → you discover the model drifted 3 weeks ago.
Every day without drift monitoring is a day your model might already be wrong.
TL;DR
- Track PSI on inference data daily
- Alert when PSI > 0.2
- Investigate before retraining
- Canary deploy retrained models
- Keep previous versions warm for rollback
Roptal automates drift monitoring, canary deployment, and rollback — all from your deployment dashboard. Stop guessing whether your model still works.