Post

Model Drift in Production: A Practitioner's Guide

A practitioner's guide to understanding, detecting, and fixing model drift in real-world production systems.

Model Drift in Production: A Practitioner's Guide

Model Drift in Production: A Practitioner’s Guide

Nobody tells you that the hardest part of deploying a model isn’t getting it to work. It’s keeping it working.

I learned this the expensive way. Deployed a classification model in March that had 92% accuracy in testing. Beautiful metrics, clean confusion matrix, stakeholders were thrilled. By July it was at 76% and I didn’t even know until a product manager asked why our recommendations suddenly felt broken.

The model hadn’t changed. The world had.

What Actually Happens

Model drift is what happens when the relationship between your inputs and outputs shifts over time. Your model learned patterns from historical data. Those patterns stop being true. The model keeps making predictions based on old patterns. Accuracy degrades.

There are three flavors and you need to watch for all of them.

Data drift is when your input distribution changes. We had a fraud detection model that learned on pre-pandemic transaction patterns. March 2020 hit and suddenly everyone was buying groceries online instead of in stores. The model had never seen these patterns. Started flagging legitimate transactions as fraud. Cost us $40K in blocked legitimate purchases before we caught it.

Concept drift is when the relationship between features and labels changes. Built a pricing model for a marketplace that worked great until a competitor launched and changed how buyers thought about value. Same features, completely different optimal prices. Model kept suggesting prices that were too high. Sales dropped twenty percent in six weeks.

Label drift is the sneaky one. This is when what you’re trying to predict changes definition. Had a customer support routing model that learned to classify urgent versus non-urgent tickets. Company changed their SLA policies. What counted as urgent shifted. Model kept using the old definition. Customers got mad because urgent issues were sitting in the wrong queues.

Detection Is Half The Battle

You can’t fix drift you don’t know about. I spent three months building a monitoring system after the July incident. Here’s what actually works.

Track your input distributions over time. For every feature, maintain a rolling baseline from training data. Compare production distributions weekly. I use KL divergence for continuous features and chi-squared tests for categorical ones. When divergence crosses a threshold I investigate.

Last month this caught a data pipeline bug where date parsing had silently broken. Dates were all coming through as January 1st. Model performance hadn’t tanked yet but the input distribution lit up every alarm. Fixed it in an hour instead of finding out three weeks later when someone complained.

Monitor prediction confidence separately from accuracy. Confidence isn’t a true probability but patterns in confidence tell you things. When average confidence drops, your model is getting confused by inputs it doesn’t recognize. When confidence stays high but accuracy drops, you’ve got concept drift and the model doesn’t know it’s wrong.

We have a dashboard that tracks both. Two months ago I noticed confidence on pricing predictions had dropped from 0.85 to 0.72 over three weeks. Nothing else looked wrong yet. Dug into it and found a new product category had launched. Model had no training data for it. Added those products to the retraining pipeline before it became a customer-visible problem.

The tricky part is you often don’t have ground truth labels in production. Can’t calculate accuracy if you don’t know the right answer.

For models that inform decisions rather than automate them, track downstream metrics. Our recommendation model suggests products but humans make the final call. We track click-through rate, add-to-cart rate, purchase rate. When those drop we know something’s wrong even if we can’t directly measure model accuracy.

For models that automate decisions, you need to label a sample. We randomly select 2% of predictions and get manual labels. Expensive and slow but it’s the only way to know if accuracy is actually degrading. Built a labeling queue that product support works through during downtime. Gives us weekly accuracy measurements with a two day lag.

Fixing It Is The Other Half

Once you catch drift you have three options. None of them are easy.

Retrain on recent data. This is the obvious move and usually the right one. Grab the last three to six months of production data, label what you need to label, retrain the model. We do this quarterly for most models. Monthly for ones operating in fast-changing domains.

The gotcha is old edge cases. Model forgets rare scenarios it doesn’t see in recent data. We had a seasonal fraud pattern that only appears in November. Retrained in March and April using six months of recent data. Model completely forgot the November pattern. Got burned the next holiday season.

Now we maintain a curated set of important edge cases and always include them in retraining. Costs us maybe 5% of model capacity but prevents catastrophic forgetting.

Online learning sounds appealing but it’s harder than it looks. Update the model continuously as new data arrives. In practice this is fragile. Bad labels corrupt the model fast. Feedback loops spiral out of control. A/B testing becomes impossible because your model is a moving target.

Tried it once on a ranking model. Worked great for three days. Then a bug in our labeling pipeline started feeding garbage data. Model learned from the garbage. Started ranking worse. Which created more garbage labels. Took us offline for six hours to restore from backup.

If you go this route you need really good monitoring and really fast rollback. And you need to be okay with the operational complexity. Most teams shouldn’t bother.

Feature engineering that’s robust to drift is the third option. Instead of retraining when the world changes, build features that adapt automatically. Use relative features instead of absolute ones. Use rates instead of raw counts. Use comparisons to recent baselines instead of static thresholds.

Changed our fraud model to use “percent above typical spend for this user” instead of absolute transaction amounts. Much more robust to inflation and income changes. Still need to retrain but we can go nine months instead of three.

What I Wish I’d Known Earlier

Drift is inevitable. You can’t prevent it. You can only catch it faster and fix it cheaper.

Build monitoring on day one, not after your first incident. The monitoring system I built after July took three months and could have been deployed before we ever went to production. Would have caught the drift at 85% accuracy instead of 76%.

Accept that retraining is an operational cost, not a failure. We budget 40 hours per quarter per model. Treat it like patching servers. Your model is running code learned from old data. Eventually you need to update.

Most importantly, don’t trust your model just because it worked yesterday. I’ve seen teams deploy models and forget about them. Accuracy silently degrades until something breaks badly enough that users complain. By then you’ve been making bad decisions for weeks.

The model that works today will not work forever. The world changes. Your model doesn’t. That gap is drift and it’s your job to close it.

Set up monitoring, schedule retraining, watch your metrics. Boring operational work that keeps your models from rotting in production.

That’s the real job. Everything else is just training.

This post is licensed under CC BY 4.0 by the author.