Lesson 11 of 30
Blue-green, canary, and rolling: three different answers to 'how do I swap old code for new code without an outage.'
15 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Once a pipeline can reliably build and test your app, the next question is mechanical: how do you actually get the new version in front of users without breaking the ones already using the old one? "Deploy" isn't a single action — it's a strategy, and the three you'll meet everywhere are blue-green, canary, and rolling.
Blue-green keeps two full, identical production environments — "blue" (live) and "green" (idle). You deploy the new version entirely to green, run your smoke tests against it while blue still serves 100% of real traffic, then flip a router or load balancer so green becomes live and blue becomes idle. Nothing gradual about it — it's a single cutover, and rollback is just flipping the router back.
Canary deploys the new version to a small slice of production capacity — say 5% of instances — and routes a matching slice of real traffic to it, while the other 95% keeps hitting the old version. You watch error rates and latency on that 5%. If it's healthy, you increase the slice (5% → 25% → 100%); if it's not, you cut traffic back to zero and only the small slice of users were ever affected.
Rolling replaces instances of the old version with the new one a few at a time — no second full environment, no traffic-splitting layer required. Take two servers out of the pool, update them, put them back, repeat until every instance is on the new version. It's what a Kubernetes Deployment does by default.
The mechanical difference shows up in what the deploy step actually points at:
# Blue-green: deploy fully, then flip a single alias
- name: Deploy to green environment
run: aws deploy create-deployment --application-name my-app \
--deployment-group-name green --s3-location bucket=my-artifacts,key=build.zip
- name: Run smoke tests against green
run: pnpm exec playwright test --config=smoke.config.ts --base-url=https://green.internal
- name: Flip router to green
run: aws elbv2 modify-listener --listener-arn $LISTENER_ARN \
--default-actions Type=forward,TargetGroupArn=$GREEN_TG_ARN
# Canary: deploy to a small target group, watch, then widen
- name: Deploy canary (5% of traffic)
run: kubectl set image deployment/my-app-canary app=my-app:${{ github.sha }}
- name: Wait and check error rate
run: ./scripts/check-canary-health.sh --window=10m --max-error-rate=1%
- name: Promote canary to 100%
run: kubectl set image deployment/my-app app=my-app:${{ github.sha }}
# Rolling: no second environment at all, just an update strategy
- name: Rolling update
run: kubectl set image deployment/my-app app=my-app:${{ github.sha }}
# deployment.spec.strategy.rollingUpdate.maxUnavailable=1 controls the pace
Same trigger (a merge to main), same artifact, three completely different mechanisms for getting it live.
Blue-green: two full environments exist side by side. Blue (v1) is live, Green (v2) is staged and ready.
Earlier lessons treated "deploy" as a single pipeline step. It isn't — it's one of these three mechanisms (or a variant), chosen based on how much you're willing to pay in idle capacity versus how fast and safe you need rollback to be. The next lesson on rollbacks builds directly on this: how fast and how safely you can undo a bad deploy is a direct consequence of which of these three strategies you picked.