Unleash

Continuous delivery for machine learning workloads

Deploying machine learning models breaks most assumptions about continuous delivery. Unlike a typical API or web service, an ML model can degrade without any code changes. Your pipeline passes all tests, but the model starts making worse predictions because the data distribution shifted.

This creates problems that traditional CD workflows weren’t designed to handle. The same practices that work for deploying a React component or a microservice—automated tests, staged rollouts, monitoring—need significant adaptation when the artifact being deployed is a trained model.

The core challenge is that ML systems change along three axes: code, model, and data. Your application code might be stable, but retraining on new data produces different model behavior. Or the code and data stay constant, but you experiment with a new architecture. Traditional software only changes along one axis.

Why standard CI/CD falls short for ML

Most CI/CD tools assume that if tests pass and the build succeeds, the deployment is safe. For a stateless API, that’s usually true. For an ML model, passing tests means you’ve verified that the model loads and can make predictions. It doesn’t tell you whether those predictions are any good.

You can’t know if a model works correctly until after deployment. This is why teams end up doing a lot of manual validation and slow, cautious rollouts. The model might perform well on held-out test data but fail on production traffic due to distribution shift, unexpected edge cases, or concept drift.

The automation that makes continuous delivery valuable—the ability to ship changes quickly with confidence—requires different mechanisms for ML. You need ways to:

  • Deploy models without immediately exposing them to production traffic
  • Compare new model versions against current production models using live data
  • Roll back to previous versions when performance degrades
  • Monitor model behavior separately from application health

Feature flags as a deployment mechanism

Feature management platforms like Unleash let you separate code deployment from feature release. For ML systems, this means you can deploy a new model to production infrastructure without actually routing traffic to it.

A feature flag wraps the model invocation, something like:

if unleash.is_enabled(“new_recommendation_model”):

    predictions = new_model.predict(features)

else:

    predictions = current_model.predict(features)

 

This gives you control over which users see predictions from which model. You can:

  • Route 5% of traffic to the new model while the rest uses the current version
  • Enable the new model only for internal users first
  • Target specific customer segments for early testing
  • Instantly revert to the previous model if metrics drop

The deployment happens independently of the release. You deploy new model artifacts to your infrastructure, verify they load correctly, then use flags to control traffic routing.

Handling the full ML pipeline

CD for machine learning needs to cover more than just the model artifact. The entire pipeline—from data ingestion through feature engineering to model training—requires automation and version control.

Some teams treat the ML pipeline itself as the primary artifact. Instead of deploying a trained model, they deploy pipeline code that can retrain models on demand. This works when:

  • Training is fast enough to happen in production
  • You need models that adapt to recent data
  • The pipeline is stable and well-tested

For most applications, though, you’re deploying pre-trained models. The training happens outside the main deployment pipeline, possibly in a completely separate environment. You might train on GPUs in a research cluster, then deploy the resulting model to CPU instances serving predictions.

This split means your CD pipeline needs to handle artifacts from multiple sources:

  • Application code from your source repository
  • Trained model files from your training infrastructure
  • Configuration for feature flags, traffic routing, and monitoring
  • Data pipeline code and schemas

Version control becomes critical. When you detect a problem with a deployed model, you need to know which training run produced it, what data it was trained on, and which hyperparameters were used.

Continuous monitoring and retraining

Models degrade over time as the world changes. A fraud detection model trained on 2023 data will perform worse in 2024 because fraud patterns evolve. This is concept drift, and it requires active monitoring.

You need metrics that track model quality, not just system health:

  • Prediction accuracy on recent data
  • Distribution shifts in input features
  • Proportion of high-confidence vs uncertain predictions
  • Drift between training data and production data

When these metrics indicate degradation, the response might be to retrain. But retraining introduces risk. The new model could perform worse than the degraded one, especially if the recent data contains quality issues or represents unusual conditions.

Feature flags provide a safety mechanism. You can:

  • Deploy the retrained model alongside the current one
  • Route a small percentage of traffic to compare performance
  • Use A/B testing to measure which model produces better business outcomes
  • Roll back immediately if the retrained model underperforms

This makes retraining less risky. You’re not replacing the production model outright. You’re testing whether the new version actually improves on the current one.

Testing ML deployments

Traditional integration tests check if components work together correctly. For ML, you need tests that verify the model makes reasonable predictions:

  • Invariance tests: predictions shouldn’t change drastically for small input perturbations
  • Directional tests: known input changes should affect predictions in expected ways
  • Boundary tests: edge cases should produce sensible outputs
  • Performance tests: inference latency stays within acceptable bounds

These tests can run in your CI pipeline, but they’re checking model behavior, not code correctness. A test failure might mean the model is wrong, or it might mean your test assumptions are wrong.

Some teams implement shadow deployments, where the new model makes predictions on production traffic but those predictions aren’t returned to users. This lets you measure performance on real data before committing to the deployment.

Orchestrating ML and application deployments

Your ML models probably depend on application code for preprocessing, feature extraction, and serving infrastructure. Changes to application code can break model deployments, and vice versa.

This creates coordination problems:

  • If you deploy new feature engineering code, do you need to retrain models?
  • If you deploy a new model, does it require application changes?
  • How do you ensure version compatibility across components?

One approach is to version models and application code together. A deployment bundles the model artifact with the exact application version it was trained against. This ensures compatibility but limits flexibility—you can’t update application code without considering model impacts.

Another approach is to define stable interfaces between components. Models consume features from a feature store with versioned schemas. The application provides those features according to the schema. As long as the interface stays consistent, models and application code can evolve independently.

Feature flags help here too. You can:

  • Deploy new feature engineering code without enabling it
  • Test that models still work with the new features
  • Gradually shift traffic to the new code path
  • Roll back if compatibility issues emerge

Building CD workflows for ML teams

Teams that successfully implement CD for ML typically combine several practices:

Automated pipeline execution: Training, validation, and packaging happen automatically when code or data changes. This might run on every commit (for fast models) or on a schedule (for expensive training).

Model registry: Trained models are versioned and stored in a central registry with metadata about training data, hyperparameters, and validation metrics. Deployment processes pull from the registry.

Staged rollouts: New models deploy first to staging environments, then to small production segments, then gradually to all traffic. Feature flags control the rollout.

Automated rollback: Monitoring detects performance degradation and triggers automatic rollback to the previous model version.

Experiment tracking: Every model version is linked to the experiment that produced it, including code version, data version, and training configuration.

Not every team needs all of this. If you’re deploying models infrequently and they’re not business-critical, simpler approaches work fine. But as model deployments become more frequent and more important, the lack of proper CD practices creates bottlenecks and risk.

The role of feature management in ML operations

Feature management platforms weren’t designed specifically for ML, but they solve several ML deployment problems:

  • Separating deployment from release reduces risk
  • Gradual rollouts provide safe testing of new models
  • Instant rollback handles model failures without redeployment
  • Targeting rules let you test models on specific user segments
  • Kill switches protect against model failures

These capabilities matter more for ML than for traditional software because you have less certainty about whether a model will work in production. Your tests are less reliable, your validation metrics might not match real-world performance, and the model’s behavior depends on data that keeps changing.

With feature flags, a deployment becomes safer. You’re not making an all-or-nothing decision. You can test cautiously, measure carefully, and revert instantly if needed. This matches how ML teams actually want to work—experimentally, with quick feedback loops and limited blast radius when things go wrong.

The alternative is to build these capabilities yourself, which many teams do. But feature management platforms provide them out of the box, already tested and scaled. You can focus on the ML-specific parts of your deployment pipeline instead of rebuilding traffic routing and rollback mechanisms.

Trunk-based development, where teams merge code to the main branch frequently, works particularly well with feature flags for ML. You can merge model changes without exposing them to users, test them in production with controlled traffic, and enable them only when validation passes. This keeps the main branch deployable while supporting rapid experimentation.

Share this article

Explore further

Product

How to think about release management

Release management controls how and when features become available to users, which differs from deployment itself. While deployment moves code into production, release management determines when that code affects user experience. The distinction matters because conflating the two creates unnecessary risk. Understanding different release strategies helps teams navigate this complexity. Deployment is not release Traditional […]