Shadow (Dark) Deployment
Mirror traffic to a new version for zero-risk validation. Responses discarded.
Shadow (Dark) deployment mirrors live production traffic to a new version running in parallel. The shadow version processes real requests but its responses are discarded -- users always get responses from the production version. This provides zero-risk validation with real-world data.
How It Works
A service mesh or proxy (Istio, Envoy) duplicates incoming requests and sends them to both production and the shadow version. Production responses go to users; shadow responses are logged and compared. You can diff response bodies, compare latency, and validate correctness without any user impact.
When to Use
- ML model updates (compare prediction quality)
- Search ranking algorithm changes
- Financial calculation engine updates
- Performance benchmarking with real traffic patterns
When NOT to Use
- Write-heavy services (risk of duplicate writes)
- Services that trigger external side effects (email, SMS, payments)
- Budget constraints (requires 2x compute for shadow)
- Simple CRUD applications where shadow adds no value
Real-World Examples
Google - Search Ranking Algorithms
Google shadow-tests search ranking changes by running new algorithms against live queries. Shadow results are compared against production results for relevance scoring. This runs for 2+ weeks before any algorithm change reaches real users.
Delta Airlines - Dynamic Pricing
Delta shadow-tested a new dynamic pricing model for 3 weeks. Real fare requests were mirrored to the new model, and prices were compared. The shadow model showed 4% revenue improvement with no increase in booking abandonment, validating the change before going live.
Step-by-Step Implementation (Istio)
1. Deploy shadow version
apiVersion: apps/v1
kind: Deployment
metadata:
name: pricing-shadow
spec:
replicas: 3
selector:
matchLabels:
app: pricing
version: shadow
template:
metadata:
labels:
app: pricing
version: shadow
spec:
containers:
- name: pricing
image: myregistry/pricing:2.0.0-shadow
env:
- name: SHADOW_MODE
value: "true" # Disable writes to external systems2. Configure traffic mirroring with Istio
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: pricing-vs
spec:
hosts:
- pricing
http:
- route:
- destination:
host: pricing
subset: production
weight: 100
mirror:
host: pricing
subset: shadow
mirrorPercentage:
value: 100.0 # Mirror 100% of traffic3. Compare responses
# Diff shadow vs production responses
# Log shadow responses and compare with production output
kubectl logs -l version=shadow --tail=100
# Check shadow error rates independently
# Shadow errors do NOT affect users but indicate issues with new versionCommon Pitfalls
| Pitfall | Symptom | Fix |
|---|---|---|
| Shadow writes to shared DB | Duplicate records, corrupted data | Use SHADOW_MODE env var to disable all write operations |
| Shadow triggers side effects | Duplicate emails, double charges | Mock or disable all external API calls in shadow mode |
| Shadow impacts production perf | Increased latency on production | Ensure shadow runs on separate resources; use async mirroring |
| 2x infrastructure cost | Higher cloud bill than expected | Mirror only a percentage of traffic; use spot instances for shadow |