Highlights
- Why models fail silently and why a green health check is not the same as a healthy model
- The four monitoring signals that matter: data drift, prediction drift, model performance, and data quality
- How drift detection works (PSI, KS, Jensen-Shannon, Wasserstein) without drowning in math
- The modern monitoring toolchain compared: Evidently, Prometheus + Grafana, WhyLabs, Arize, Fiddler, NannyML
- A runnable drift check with Evidently that you can drop into CI or a scheduled job
- Best practices for baselines, thresholds, and beating alert fatigue
- Closing the loop: how a drift alert becomes an automatic retrain
The model shipped at 95% accuracy. Everyone moved on to the next project. Eight months later, a product manager notices conversion is down and starts asking questions, and only then does someone check: the model is now making correct calls about 60% of the time. It never threw an error, never paged anyone, never showed up in a dashboard. It just quietly got worse as the world drifted away from its training data, and the first "alert" was a human noticing lost revenue.
This is the defining failure mode of production machine learning, and it is not rare. A 2022 study in Scientific Reports found temporal performance degradation in 91% of the model-and-dataset pairs it tested across healthcare, finance, transportation, and weather. Models do not stay good on their own. The discipline that catches this decay before your users do is model monitoring: a system that watches your live model's inputs, outputs, and accuracy, and raises a flag when something shifts. This guide covers what to monitor, the current tooling, the best practices that keep alerts useful, and a runnable drift check you can wire into a pipeline today.
Why Monitor Models in Production
Traditional software fails loudly. A bug throws an exception, a service returns a 500, a pager goes off. Machine learning fails quietly. A model keeps returning 200 OK and well-formed predictions while those predictions slowly drift from reality, because the data arriving in production no longer looks like the data it trained on. Nothing crashes. The accuracy just erodes.
That is why monitoring is not optional infrastructure you add later; it is part of shipping the model. The economics are simple: a monitoring program that catches degradation when it affects 5% of outputs is far cheaper than one that catches it after it has touched a quarter of revenue-generating decisions. The longer the silence, the larger the gap and the harder the post-mortem, because the team has to reconstruct not just what broke but how long it has been broken.
Mechanically, model monitoring is a service that sits alongside your prediction service. It samples incoming inputs and the predictions the model made, computes metrics from them, and forwards those metrics to an observability platform that can dashboard and alert on them. Get that in place and "the model got worse" becomes a graph with a threshold line, not a quarterly surprise.
The Four Signals Worth Monitoring
Good monitoring watches several signals at once, because each answers a different question and each fails to catch what the others see. There are four that matter for the model itself, plus the operational signals you already monitor for any service.
The "Needs labels?" column is the most important insight on this table. Model performance is the metric you actually care about, but it is the one you usually cannot measure in real time, because the ground truth (did the user actually churn? was the transaction actually fraud?) arrives days or weeks later, if at all. Data drift and prediction drift need no labels, so they are available immediately. That makes drift your early-warning system: it tells you the inputs have changed and performance is probably about to suffer, long before the labels confirm it.
How Drift Detection Actually Works
Drift detection compares two distributions: a reference (usually your training or validation data) and the current production window. For each feature, a statistical test measures how far the current distribution has moved from the reference, and you flag the feature as drifted when that distance crosses a threshold. Common tests include the Population Stability Index (PSI), the Kolmogorov-Smirnov (KS) test, Jensen-Shannon distance, and the Wasserstein distance; tools like Evidently ship 20+ of them and pick sensible defaults by data type.
You do not need to derive the math to use it. The practical loop is: keep a fixed reference, score each production window against it, and alert when the share of drifted features (or a key feature) exceeds your tolerance. The deeper distinction between data drift and concept drift, and how to tell them apart, is its own topic; we cover it in our dedicated guide to data drift and concept drift.
The Model Monitoring Toolchain
You can assemble a production-grade monitoring stack entirely from open source, or buy a managed platform. The right choice depends on scale, compliance needs, and how much you want to operate yourself.
- Evidently is the open-source workhorse: a Python library with 100+ metrics and 20+ drift tests that generates reports and integrates with Prometheus and Grafana.
- Prometheus + Grafana are the metrics-and-dashboards backbone; Evidently (or your own exporter) feeds them the numbers, Prometheus stores and alerts, Grafana visualizes.
- WhyLabs focuses on scalable, real-time monitoring and went open source under Apache 2.0 in 2025.
- Arize and Fiddler are managed observability platforms strong on explainability, embeddings, and bias/fairness for regulated use.
- NannyML specializes in the hard problem above: estimating model performance when labels are delayed or missing.
For most teams starting out, Evidently for the metrics plus Prometheus and Grafana for storage, dashboards, and alerts is a complete, free, production-grade stack. Reach for a managed platform when scale, compliance, or built-in explainability justify the cost.
Build a Drift Check You Can Automate
Here is a real, runnable data-drift check using Evidently. It compares a reference dataset (what the model trained on) against a current window (recent production data) and reports how many features drifted, so you can turn that into an alert or a retraining trigger.
One important note: Evidently's API changed in the 0.6 and 0.7 releases, and most tutorials online still use the old from evidently.report import Report, which no longer exists. The imports below are the current 0.7 API.
# requirements: evidently==0.7.* scikit-learn pandas
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from evidently import Report, Dataset, DataDefinition
from evidently.presets import DataDriftPreset
iris = load_iris(as_frame=True)
features = list(iris.feature_names)
# reference = data the model trained on; current = recent production data
reference, current = train_test_split(
iris.frame[features], test_size=0.5, random_state=42, stratify=iris.frame["target"]
)
schema = DataDefinition(numerical_columns=features)
report = Report([DataDriftPreset()])
snapshot = report.run(
reference_data=Dataset.from_pandas(reference, data_definition=schema),
current_data=Dataset.from_pandas(current, data_definition=schema),
)
snapshot.save_html("drift_report.html") # interactive report for humans
drift = snapshot.dict()["metrics"][0]["value"] # {"count": ..., "share": ...}
print(drift)
# wire it into automation: alert or retrain when too many features drift
if drift["share"] > 0.3:
raise SystemExit("data drift exceeds 30% of features; trigger retraining")On two samples of the same distribution, this prints {"count": 0.0, "share": 0.0}: no drift. Shift one of the four features (for example, add a constant to petal length (cm) to simulate a sensor recalibration) and the share jumps to 0.25, one of four features flagged, and Evidently writes an interactive HTML report showing exactly which feature moved and by how much.
That last if is the bridge from monitoring to action. Run this on a schedule with GitHub Actions or Jenkins and a drift breach can fail the job and open an alert; better still, have it trigger the retraining pipeline directly, the loop we describe in our guides on CI/CD for machine learning and automating ML workflows. Monitoring that nobody acts on is just a prettier way to be surprised.
Want to learn MLOps by doing, not just reading?
Our 100 Days of MLOps challenge on KodeKloud Engineer walks you through real production scenarios, one hands-on lab at a time. You'll touch MLflow, Kubeflow, model deployment, monitoring, and the same workflows companies actually run in 2026.
Start the Challenge →Best Practices for Model Monitoring
1. Set a reference baseline and monitor against it
Drift is meaningless without a "normal" to compare to. Freeze a reference dataset (your training or validation set) and a baseline for every metric at deploy time, then measure every production window against it. Re-baseline deliberately when you retrain, not silently.
2. Use drift as your early-warning system
Because data and prediction drift need no labels, they are available immediately, while true performance lags behind label collection. Lead with drift to get early warning, and treat a drift spike as "investigate now," not "wait for the accuracy numbers."
3. Track real performance whenever labels arrive
Drift tells you inputs changed; only ground truth tells you the model is actually wrong. As labels come in (even delayed), compute real accuracy, AUC, or RMSE against them, and use tools like NannyML to estimate performance in the gap before labels land.
4. Tune thresholds to beat alert fatigue
A monitor that pages on every tiny fluctuation gets muted, and a muted monitor catches nothing. Set thresholds with someone who knows the model, alert on sustained or significant shifts rather than single noisy windows, and route low-severity drift to a dashboard instead of a pager.
5. Close the loop to retraining
The point of catching drift is to fix it. Connect alerts to action: at minimum a ticket and a human review, at best an automatic retraining run gated by a quality check so a drift-triggered retrain cannot ship a worse model.
6. Monitor data quality and operations too
Plenty of "model" incidents are really a broken upstream pipeline: a feed that started sending nulls, a renamed column, a unit change. Validate schema, missing values, and ranges on the way in, and keep watching latency, throughput, and error rates alongside the model metrics.
What You've Set Up
Put together, the monitoring you now have in place:
- Watches four signals, not just uptime: data drift, prediction drift, performance, and data quality.
- Leads with label-free drift for early warning, and confirms with real performance as labels arrive.
- Runs a concrete drift check (Evidently) that produces both a human-readable report and a machine-readable share you can threshold.
- Feeds an observability stack (Prometheus and Grafana, or a managed platform) for dashboards and alerts.
- Closes the loop, turning a drift breach into a retraining trigger behind a quality gate.
Common Gotchas
- No reference baseline. Drift needs a fixed "normal" to compare against; without a frozen reference, your numbers mean nothing.
- Watching only accuracy. Labels lag, so accuracy alone leaves you blind for days or weeks. Monitor drift for early warning.
- Alert fatigue. Over-sensitive thresholds train your team to ignore the monitor. Tune for sustained, meaningful shifts.
- Drift detected, nothing happens. An alert with no owner and no action is theater. Wire it to a ticket or a retrain.
- Using an outdated Evidently API. The
evidently.reportimport is gone in 0.7; usefrom evidently import Report, Dataset, DataDefinition. - Ignoring data quality. A nulls-filled feed or a renamed column will tank a model just as fast as real drift, and it is easier to catch.
Conclusion
Models do not fail like software; they fade. A 95% model can decay to 60% without a single error in the logs, and a study across four industries found that pattern in 91% of cases. Monitoring is how you make that decay visible: watch the four signals, lead with label-free drift because real performance arrives late, and put a fixed reference and sensible thresholds behind every alert.
Start simple. Evidently for drift and quality, Prometheus and Grafana for dashboards and alerts, is a free, production-grade stack you can stand up this week. Then connect the alerts to action, ideally an automatic retrain behind a quality gate, so monitoring stops being a report you read after the fact and becomes the thing that keeps your model honest.
Ready to Build It, Not Just Read About It?
Reading about monitoring is one thing. Setting a reference baseline, watching a drift score cross its threshold on real production data, and wiring that alert into an automatic retrain are entirely different skills, and they only come from doing the work. That's what the 100 Days of MLOps challenge on KodeKloud is built for: real environments, real tools, auto-validated tasks across the full lifecycle, with Evidently, Prometheus, and Grafana for monitoring and GitOps for everything else. By the end you will have operated the kind of monitoring this guide describes, with the muscle memory to prove it. Create your free KodeKloud account
Q1: What is the difference between data drift and concept drift?
Data drift means the input distribution changed: the features arriving in production no longer look like the training data. Concept drift means the relationship between inputs and the target changed, so the same input now maps to a different correct answer. Data drift is detectable without labels and is an early warning; concept drift usually shows up as falling performance once labels arrive. Both call for retraining. We cover the distinction in depth in our guide to data drift and concept drift.
Q2: How often should I check for drift?
Match the cadence to how fast your data moves and how fast you can act. Batch systems often check daily or per batch; high-velocity domains like fraud or ads check hourly or in near real time. Running a drift check on a schedule (for example, a daily GitHub Actions or Jenkins job) is a sensible default, paired with a dashboard for continuous visibility.
Q3: Do I need labels to monitor a model?
Not for everything, and that is the key insight. Data drift, prediction drift, and data quality need no labels and are available immediately. True performance metrics (accuracy, AUC, RMSE) do need ground truth, which often arrives late. Lead with the label-free signals for early warning, and add performance tracking and label-free performance estimation (NannyML) for when labels lag.
Q4: Can I do model monitoring with free, open-source tools?
Yes. Evidently (drift and quality metrics) plus Prometheus (storage and alerting) and Grafana (dashboards) is a complete, free, production-grade monitoring stack, and several platforms like WhyLabs and NannyML are open source too. Managed platforms such as Arize and Fiddler add scale, explainability, and compliance features, which you pay for when you need them.
Sources: Vela et al., "Temporal quality degradation in AI models," Scientific Reports (2022); Evidently (open source); Evidently data drift documentation; Datadog: ML model monitoring best practices; NannyML: estimating performance without labels.
Discussion