Blue-Green vs Canary Deployments Explained
Compare blue-green and canary deployment strategies with practical examples to choose the right zero-downtime release approach for your team.
What you'll learn
- ✓How blue-green deployments work end to end
- ✓How canary deployments shift traffic gradually
- ✓Trade-offs between the two strategies
- ✓Practical Kubernetes examples for both
- ✓When to use each approach
Prerequisites
None — this post is self-contained.
Shipping code to production without downtime is table stakes for modern teams. Two strategies dominate the conversation: blue-green deployments and canary deployments. Both eliminate the maintenance window, but they manage risk in fundamentally different ways. This article breaks down the mechanics, trade-offs, and practical implementation of each so you can make an informed choice.
Blue-Green Deployments
A blue-green deployment maintains two identical production environments. At any given time one environment (blue) serves all live traffic while the other (green) sits idle or runs the new version. When you are ready to release, you switch the router so that all traffic moves from blue to green in a single cut.
The beauty is simplicity. You deploy the new version to the idle environment, run your smoke tests against it, and flip the switch. If something is wrong, you flip back. Rollback is instant because the old environment is still running.
Kubernetes Example
You can implement blue-green with two Deployments and a Service selector. Start with the blue version serving traffic:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-blue
spec:
replicas: 3
selector:
matchLabels:
app: api
slot: blue
template:
metadata:
labels:
app: api
slot: blue
spec:
containers:
- name: api
image: myregistry/api:1.4.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: api
spec:
selector:
app: api
slot: blue # points to blue
ports:
- port: 80
targetPort: 8080
Deploy the green version alongside it:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-green
spec:
replicas: 3
selector:
matchLabels:
app: api
slot: green
template:
metadata:
labels:
app: api
slot: green
spec:
containers:
- name: api
image: myregistry/api:1.5.0
ports:
- containerPort: 8080
Once smoke tests pass against the green pods, switch the Service selector:
kubectl patch service api \
-p '{"spec":{"selector":{"slot":"green"}}}'
All traffic now hits version 1.5.0. To roll back, patch the selector back to blue. After you gain confidence, scale down the blue Deployment.
Pros and Cons
Blue-green gives you instant rollback and a dead-simple mental model. The downside is cost: you need double the infrastructure during the transition window. It is also all-or-nothing. Every user gets the new version at the same moment, so a subtle bug affects 100 percent of traffic the instant you flip.
Canary Deployments
A canary deployment takes the opposite approach. Instead of switching all traffic at once, you route a small percentage to the new version and gradually increase it as metrics confirm the release is healthy.
The name comes from the coal mine canary: a small group of requests acts as the early warning system. If error rates, latency, or business metrics degrade, you halt the rollout and route everything back to the stable version.
Kubernetes Example with Ingress Weights
Many ingress controllers support traffic splitting with annotations. Here is an example using NGINX Ingress:
# Stable ingress - receives most traffic
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-stable
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-stable
port:
number: 80
---
# Canary ingress - receives a percentage
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "10"
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-canary
port:
number: 80
Start at 10 percent. Monitor your dashboards. If everything looks good, bump the weight to 25, then 50, then 100. Each step is a chance to catch problems before they reach the full user base.
Automated Canary with Flagger
Flagger automates the weight progression and analysis. Define a Canary resource:
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: api
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api
service:
port: 80
analysis:
interval: 1m
threshold: 5
maxWeight: 50
stepWeight: 10
metrics:
- name: request-success-rate
thresholdRange:
min: 99
interval: 1m
- name: request-duration
thresholdRange:
max: 500
interval: 1m
Flagger watches the success rate and latency. If both stay within thresholds, it increments the canary weight by 10 percent every minute until it reaches 50 percent, then promotes. If metrics breach the threshold five times, it rolls back automatically.
Comparing the Two Strategies
| Factor | Blue-Green | Canary |
|---|---|---|
| Blast radius | 100% on switch | Starts small, grows |
| Rollback speed | Instant (switch back) | Fast (reset weight) |
| Infrastructure cost | 2x during deploy | Marginal overhead |
| Complexity | Low | Medium to high |
| Best for | Stateless apps, small teams | High-traffic services, risk-averse orgs |
Blue-green suits teams that want simplicity and can afford the extra capacity. Canary suits teams running high-traffic services where exposing a bug to every user at once is unacceptable.
Database Migrations
Neither strategy solves database schema changes automatically. Both require backward-compatible migrations. The rule is: the old version and the new version must be able to run against the same database schema simultaneously. Use expand-and-contract migrations. Add the new column first, deploy code that writes to both old and new columns, then drop the old column in a later release.
Choosing the Right Strategy
Start with blue-green if your service is small, your team is learning, or your deployments are infrequent. The cognitive overhead is minimal and the rollback story is excellent.
Move to canary when your service handles enough traffic that a bad deploy causes real damage, when you have monitoring mature enough to detect regressions automatically, or when you want to combine deployment with experimentation.
Many teams use both. Blue-green for internal services where the blast radius is contained. Canary for the public-facing API where a one percent error spike means thousands of failed requests.
Wrap-up
Blue-green and canary deployments both eliminate downtime, but they manage risk differently. Blue-green is simple and gives you an instant rollback switch. Canary is more nuanced and limits blast radius by shifting traffic gradually. Pick the one that matches your traffic volume, monitoring maturity, and risk tolerance, and remember that the best deployment strategy is the one your team actually understands and trusts.
Related articles
- DevOps Zero-Downtime Deployments: Strategies and Patterns
Master zero-downtime deployment strategies including rolling updates, blue-green, canary, and feature flags. Learn practical patterns for Kubernetes and cloud platforms.
- Backend Health Checks and Readiness Probes Done Right
Design health check endpoints that actually help. Covers liveness vs readiness, dependency checks, degraded states, and Kubernetes probe configuration.
- Kubernetes Kubernetes Readiness vs Liveness Probes: A Practical Guide
Understand the difference between readiness and liveness probes in Kubernetes, when to use each, and how to configure them safely in production workloads.
- DevOps Chaos Engineering: Test Your System's Resilience
Learn chaos engineering principles and tools. Run controlled experiments with Chaos Monkey, Litmus, and Gremlin to find weaknesses before they cause real outages.