Definition
- Recreate – kills the old version then starts the new, accepting downtime but guaranteeing no version overlap.
- Rolling – replaces pods incrementally for zero downtime, at the cost of briefly running two versions and a slow rollback.
- Blue-Green – runs two complete environments and flips a traffic switch for instant cutover and instant rollback, at double the infrastructure cost.
- Canary – shifts a small percentage of real traffic to the new version while watching metrics, expanding only if healthy.
- A/B testing – routes users by an attribute to compare a business outcome between two experiences.
- Shadow (traffic mirroring) – sends a copy of production requests to the new version while the old version still serves; the new version's responses are discarded.
- Zero downtime – an objective that several strategies can achieve, not a strategy itself.
Picture National Bank of India opening a renovated counter. Recreate closes the old counter before opening the new one. Rolling swaps staff one at a time. Blue-Green builds a whole second counter and simply redirects the queue to it, keeping the old one ready in case of trouble. Canary sends every tenth customer to the new counter and watches if they are served well before sending more. A/B sends premium customers to one counter and regular customers to another to see which design closes more loans. Shadow quietly has the new counter process photocopies of real requests without giving the customer the result, just to see if it would cope.
Understanding the Concepts
What are deployment strategies?
Deployment strategies are patterns for releasing a new version of a service, each trading off downtime, rollback speed, infrastructure cost, and risk differently. Choosing the right strategy for a given service is a core DevOps decision.
# The strategy field in a Kubernetes Deployment
spec:
strategy:
type: RollingUpdate # or Recreate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
How does Recreate work?
Recreate terminates all old instances and then starts the new ones. Its downtime is high because there is a gap with no running instances. Its rollback is as slow as a full redeploy of the old version. Its infrastructure cost is low because you never run extra instances. Its risk is high because all users hit the new version at once with no gradual exposure.
# Recreate for the Settlement Scheduler
apiVersion: apps/v1
kind: Deployment
metadata:
name: settlement-scheduler
spec:
replicas: 1
strategy:
type: Recreate
template:
spec:
containers:
- name: scheduler
image: registry.nbi.com/settlement:3.1.0
How does Rolling work?
Rolling replaces instances a few at a time. Its downtime is zero when readiness probes and graceful shutdown are correct. Its rollback is slow because you must roll the old version back pod by pod. Two versions coexist during the roll, so they must be compatible.
# Trigger a rolling update by changing the image
kubectl set image deployment/transfer-service \
transfer-service=registry.nbi.com/transfer-service:2.6.0
# Watch the rollout
kubectl rollout status deployment/transfer-service
Waiting for deployment "transfer-service" rollout to finish:
3 of 4 updated replicas are available...
deployment "transfer-service" successfully rolled out
How does Blue-Green work?
Blue-Green runs two full environments, the current blue and the new green. You deploy and fully test green while blue serves all traffic, then flip the load balancer so all traffic goes to green instantly. Rollback is the fastest of all: flip back to blue.
# Blue environment Service
apiVersion: v1
kind: Service
metadata:
name: transfer-service
spec:
selector:
app: transfer-service
version: blue # Points to blue pods
ports:
- port: 80
targetPort: 8080
---
# Switch to green by changing the selector
apiVersion: v1
kind: Service
metadata:
name: transfer-service
spec:
selector:
app: transfer-service
version: green # Flip! Now points to green pods
ports:
- port: 80
targetPort: 8080
# Flip traffic from blue to green
kubectl patch service transfer-service \
-p '{"spec":{"selector":{"version":"green"}}}'
# Instant rollback to blue
kubectl patch service transfer-service \
-p '{"spec":{"selector":{"version":"blue"}}}'
How does Canary work?
Canary shifts a small slice of real traffic, perhaps five percent, to the new version while watching error rates, latency, and business metrics. If the canary stays healthy you expand; if it degrades you abort.
# Canary with Istio VirtualService
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: transfer-service
spec:
hosts:
- transfer-service
http:
- route:
- destination:
host: transfer-service
subset: stable
weight: 95
- destination:
host: transfer-service
subset: canary
weight: 5 # 5% canary traffic
# Promote canary to 100% after metrics look good
kubectl apply -f virtualservice-full-rollout.yaml
# Abort canary -- send all traffic back to stable
kubectl apply -f virtualservice-rollback.yaml
How do all strategies compare?
| Strategy | Downtime | Rollback speed | Infra cost | Risk | Best for |
|---|---|---|---|---|---|
| Recreate | High | Slow (redeploy) | Low | High | Singletons, off-hours batch |
| Rolling | Zero | Slow (pod by pod) | Low-moderate | Moderate | Stateless services |
| Blue-Green | Zero | Instant (flip back) | High (2x infra) | Moderate | Instant reversibility |
| Canary | Zero | Fast (abort canary) | Moderate | Lowest | High-risk critical paths |
| A/B | Zero | Fast | Moderate | Low | Business experiments |
| Shadow | Zero (user) | N/A (no real traffic) | High | Zero (user) | Pre-cutover validation |
Why is zero downtime an objective rather than a strategy?
Zero downtime names a property you want, not a mechanism. Rolling, Blue-Green, Canary, and Shadow can all deliver zero user-facing downtime, each by a different mechanism. Saying "we want zero downtime" does not tell you how; you still choose a strategy based on rollback speed, cost, and how gradually you want to expose the change.
# Zero downtime is verified the same way regardless of strategy
while true; do
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
http://transfer.nbi.com/health)
echo "$(date +%H:%M:%S) $HTTP_CODE"
sleep 0.5
done
14:05:01 200
14:05:01 200
14:05:02 200
... (no 5xx if the strategy and probes are correct)
How does expand-and-contract keep schema changes safe?
The expand-and-contract pattern splits a breaking schema change into three steps so both old and new code can operate safely during the overlap window.
-- EXPAND: add new column, old code ignores it
ALTER TABLE accounts ADD COLUMN iban VARCHAR(34);
-- MIGRATE: new code writes to both, backfill old rows
UPDATE accounts SET iban = 'IN' || sort_code || account_number
WHERE iban IS NULL;
-- CONTRACT: remove old column only after old code is gone
ALTER TABLE accounts DROP COLUMN sort_code;
package com.bank.service;
import java.math.BigDecimal;
public class TransferService {
// During expand phase, write to BOTH columns
public void initiateTransfer(String fromIban, String toIban,
BigDecimal amount) {
// New code writes to iban column
// Also writes to legacy sort_code + account_number
// so old code can still read
accountRepository.saveDualFormat(fromIban, toIban, amount);
}
}
What are common mistakes?
The most common mistake is choosing RollingUpdate for a service that holds exclusive state, or choosing Recreate for a customer-facing API where downtime is unacceptable.
# WRONG: Recreate for a customer-facing API -- causes downtime
apiVersion: apps/v1
kind: Deployment
metadata:
name: transfer-service
spec:
strategy:
type: Recreate # Customers see errors during deploy!
# CORRECT: RollingUpdate for a customer-facing API
apiVersion: apps/v1
kind: Deployment
metadata:
name: transfer-service
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
What should a senior engineer know?
A senior engineer matches the strategy to the service and the change. At National Bank of India, the Transfer API uses Rolling for routine releases, Blue-Green for major version changes where instant rollback is essential, and Canary for high-risk changes like fraud-scoring rewrites. The Settlement Scheduler uses Recreate because it is a singleton. Shadow mirroring is used to validate a new payment-processing engine under real load before any customer ever touches it.
Visual Overview
Recreate Rolling Blue-Green
────────── ────────── ──────────
[OLD] ──stop──→ [OLD][OLD][OLD] [BLUE]────traffic────→
[ gap ] [OLD][OLD][NEW] │
[NEW] ──start──→ [OLD][NEW][NEW] [GREEN]──test──→
[NEW][NEW][NEW] │
flip! [GREEN]←──traffic
Canary Shadow
────────── ──────────
95% → [STABLE] [OLD]────serves────→ customer
5% → [CANARY] [NEW]←──mirror──→ (discard response)
watch metrics validate performance
Key Takeaway
There are six deployment strategies, and comparing them along four axes: downtime, rollback speed, infrastructure cost, and risk, is the clean way to present them in an interview. Recreate accepts downtime for simplicity. Rolling achieves zero downtime at low cost but with slow rollback. Blue-Green gives the fastest rollback at double the infrastructure. Canary has the lowest risk by exposing only a fraction of traffic. Shadow validates under real load with zero user risk.
The key insight is that zero downtime is an objective, not a strategy. Rolling, Blue-Green, Canary, and Shadow can all achieve it by different mechanisms. Saying "we want zero downtime" does not choose the approach; you still decide based on how fast you need to roll back, how much infrastructure you can afford, and how gradually you want to expose the change.
The piece that matters most for banking is expand-and-contract for schema changes: add the new structure first, migrate data, remove the old structure only after all old code is gone. Without it, any strategy where two versions coexist will break during the overlap.
Remember one sentence: zero downtime is the destination, and each strategy is a different road to it, chosen by how much you are willing to spend on rollback speed, risk reduction, and infrastructure.
---