Reliability Patterns
SLA, SLO, and SLI
SLI (Service Level Indicator) — A quantitative measure of a specific aspect of service behavior.
- Latency: p99 request latency < 200ms
- Throughput: successful requests per second
- Error rate: percentage of failed requests
- Availability: fraction of time service is operational
SLO (Service Level Objective) — An internal target value for an SLI over a specified time window.
- "99.9% of requests complete in under 200ms over a 30-day rolling window"
- "Error rate must stay below 0.1% per month"
SLA (Service Level Agreement) — A contractual commitment with customers defining expected service levels and consequences of missing them.
- SLA = SLO + consequences (credits, refunds)
- SLA should always be slightly worse than SLO to maintain buffer
Error Budget:
- Error budget = 1 - SLO. If SLO is 99.9%, error budget is 0.1%.
- Once error budget is consumed, freeze feature releases until budget resets.
- Prevents reliability erosion from velocity pressure.
Redundancy Strategies
| Strategy | Description | Pros | Cons | Use Case |
|---|---|---|---|---|
| Active-Active | All instances serve traffic simultaneously | Max throughput, no failover delay | Data consistency complexity | Stateless services, CDN |
| Active-Passive | One primary, others on standby | Simpler data sync | Waste of standby resources | Databases, legacy systems |
| N+1 | N active + 1 spare | Balanced cost/reliancy | Limited additional capacity | General microservices |
| N+K | N active + K spares | Higher fault tolerance | More resource waste | Mission-critical systems |
Active-Active Design:
- All nodes accept reads and writes
- Conflict resolution needed (last-writer-wins, CRDTs, vector clocks)
- Global load balancer routes to nearest healthy region
- Example: DynamoDB Global Tables, Cassandra multi-DC
Active-Passive Design:
- Primary handles all write traffic
- Replica receives replicated data but does not serve production traffic
- Failover: promote replica to primary, update DNS/load balancer
- Failover time: seconds to minutes depending on detection mechanism
- Example: RDS Multi-AZ, traditional MySQL master-slave
Circuit Breaker Pattern
The circuit breaker prevents cascading failures by short-circuiting calls to a failing dependency.
Three States:
Closed (Normal operation)
- Requests pass through normally
- Failures are counted
- When failure threshold is reached → transition to Open
Open (Failing fast)
- All requests are immediately rejected without calling the dependency
- After a timeout period → transition to Half-Open
Half-Open (Probe)
- A limited number of test requests are allowed through
- If they succeed → transition to Closed
- If they fail → transition back to Open
Closed → (failure threshold exceeded) → Open → (timeout expires) → Half-Open
↑ |
└────────────── (probe succeeds) ─────────────────────────┘
↑ |
└────────────── (probe fails) ────────────────────────────┘
Configuration Parameters:
- Failure threshold: number of failures before opening (e.g., 5 failures in 10s)
- Open duration: how long to stay open (e.g., 30 seconds)
- Half-open max calls: number of probe requests (e.g., 3)
- Fallback behavior: return cached data, default response, or error
Implementation: Hystrix (Netflix, now deprecated), Resilience4j, Polly (.NET)
Retry with Exponential Backoff and Jitter
Exponential Backoff:
- Wait time doubles after each retry: 1s, 2s, 4s, 8s, 16s
- Prevents thundering herd by spacing out retry attempts
- Set a maximum retry count (e.g., 5) and maximum delay cap
Jitter:
- Adds randomness to retry delays to prevent synchronized retries
- Types: full jitter, equal jitter, decorrelated jitter
Full Jitter: sleep = random(0, min(cap, base * 2^attempt))
Equal Jitter: sleep = min(cap, base * 2^attempt) / 2 + random(0, min(cap, base * 2^attempt) / 2)
Decorrelated: sleep = min(cap, random(base, previous_sleep * 3))
Best Practices:
- Only retry idempotent operations (GET, PUT, DELETE with idempotency keys)
- Distinguish retryable errors (503, timeout) from non-retryable (400, 401, 403)
- Use circuit breaker alongside retries to avoid hammering a failing service
Bulkhead Pattern
Isolates components so a failure in one does not cascade to others. Named after ship bulkheads that prevent flooding from spreading.
Implementation Strategies:
- Thread pool isolation: Each dependency gets its own thread pool. If Service A's pool is exhausted, Service B's pool is unaffected.
- Semaphore isolation: Limit concurrent calls per dependency using semaphores.
- Connection pool isolation: Separate database connection pools per service.
Service A → [Thread Pool: 10 threads] → Dependency A
Service A → [Thread Pool: 10 threads] → Dependency B
Service A → [Thread Pool: 5 threads] → Dependency C
Example: Netflix Hystrix bulkhead configuration:
- Each downstream service gets its own command group
- Thread pool size tuned per dependency based on latency and throughput
- When pool is full, requests fail fast with fallback
Chaos Engineering Principles
Chaos engineering proactively introduces failures to discover weaknesses before they cause outages.
Netflix's Chaos Monkey:
- Randomly terminates production instances during business hours
- Forces engineers to build resilient systems that handle instance loss
- Part of the Simian Army: Latency Monkey, Conformity Monkey, Security Monkey
Principles (from "Chaos Engineering" book):
- Build a hypothesis around steady-state behavior
- Vary real-world events (network latency, disk failures, process crashes)
- Run experiments in production (or production-like environments)
- Automate experiments to run continuously
- Minimize blast radius
Types of Fault Injection:
- Network: partition, latency, packet loss, DNS failures
- Infrastructure: terminate instances, fill disk, exhaust CPU
- Application: throw exceptions, return errors, corrupt state
- Time: advance clocks, trigger cron jobs early
Tools: Chaos Monkey, Litmus (Kubernetes), Gremlin, AWS Fault Injection Simulator
Payment Processing Reliability Example
A payment system must be highly reliable because failures directly impact revenue and customer trust.
Architecture:
Client → API Gateway → Payment Service → Payment Gateway (Stripe/PayPal)
↓
Transaction DB (Primary)
↓
Transaction DB (Replica)
↓
Message Queue (SQS/Kafka)
↓
Notification Service
Reliability Measures:
- Idempotency keys: Every payment request includes a unique idempotency key. Retries don't create duplicate charges.
- Circuit breaker on payment gateway: If Stripe is down, circuit opens after 3 failures. Fallback: queue payment for retry, return "payment pending" to user.
- Retry with backoff: Gateway timeouts retried with exponential backoff (max 3 retries).
- Dual payment providers: Stripe as primary, PayPal as fallback. If Stripe circuit is open, route to PayPal.
- Transactional outbox pattern: Write payment event to DB and message queue in same transaction. Ensures exactly-once processing downstream.
- SLO: 99.99% availability (52 minutes downtime per year), p99 latency < 500ms.
- Active-active: Two regions, each processing independent payment streams with shared DB replication.
- Monitoring: Real-time alerting on error rate > 0.1%, latency p99 > 1s, payment success rate < 99.5%.
Fault Tolerance
Defining Fault Tolerance
Fault tolerance is the ability of a system to continue operating correctly despite the failure of one or more components. A fault-tolerant system degrades gracefully rather than failing completely.
Key Concepts:
- Failure: A component stops working entirely
- Fault: A defect or anomaly in the system (could be partial)
- Error: An incorrect system state resulting from a fault
- Fault Tolerance: System continues operating correctly despite faults
Graceful Degradation
Instead of failing entirely, the system reduces functionality:
- Feature degradation: Disable non-critical features (recommendations, analytics) while keeping core functionality (purchases, search)
- Quality degradation: Serve lower-resolution images, skip personalization
- Capacity degradation: Serve fewer users but maintain quality for those served
Netflix Example: When a dependency fails, Netflix serves cached content instead of personalized recommendations. Users lose recommendations but can still browse and watch.
Amazon Example: If the recommendation engine is down, product pages still load with static content. "Frequently bought together" might be cached or empty rather than blocking page load.
Replication Strategies
Synchronous Replication:
- Write is confirmed only after all replicas acknowledge
- Guarantees zero data loss (RPO = 0)
- Higher write latency
- Used for: financial systems, leader election
Asynchronous Replication:
- Write is confirmed after primary acknowledges
- Replicas may lag behind primary
- Lower write latency but potential data loss
- Used for: read replicas, analytics, most web applications
Semi-synchronous Replication:
- Write confirmed after at least one replica acknowledges
- Balance between durability and latency
- Used for: MySQL semi-sync, Amazon RDS Multi-AZ
Health Checks and Self-Healing
Liveness Probes:
- Check if the application process is running
- If liveness fails → restart the container
- Kubernetes example:
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
Readiness Probes:
- Check if the application is ready to serve traffic
- If readiness fails → remove from load balancer (don't restart)
- Useful during startup or when temporary overload
readinessProbe:
httpGet:
path: /health/ready
port: 8080
periodSeconds: 10
Startup Probes:
- For slow-starting applications
- Prevents liveness probe from killing the app before it starts
startupProbe:
httpGet:
path: /health/startup
port: 8080
failureThreshold: 30
periodSeconds: 10
Failure Detection
Heartbeat Mechanism:
- Nodes send periodic heartbeats (e.g., every 5 seconds)
- If no heartbeat received for N intervals → node declared dead
- Too short → false positives; too long → slow detection
Gossip Protocol:
- Each node randomly communicates with a few peers
- Failure information propagates through the cluster
- Used by: Cassandra (Phi Accrual Failure Detector), Consul, Serf
- Eventually consistent but scales well
Phi Accrual Failure Detector:
- Outputs a suspicion level (phi) rather than binary alive/dead
- Phi increases with time since last heartbeat
- Threshold is adaptive based on network conditions
- More nuanced than simple timeout-based detection
Quorum and Consensus
Quorum:
- Minimum number of nodes that must agree for a decision
- In a cluster of N nodes, quorum = N/2 + 1
- Example: 5-node cluster needs 3 nodes for quorum
- Ensures consistency: at most one partition can have quorum
Raft Consensus:
- Leader election: one leader handles all writes
- Log replication: leader replicates log entries to followers
- Safety: committed entries are never lost
- Used by: etcd, Consul, CockroachDB
Paxos:
- More complex but theoretically foundational
- Used by: Google Chubby, Apache ZooKeeper (ZAB variant)
Timeouts and Deadlines
Setting Timeouts:
- Timeout should be based on observed latency distribution (p99 or p99.9)
- Too short → false failures; too long → slow failure detection
- Cascading: total timeout = sum of downstream timeouts (bad) or use deadline propagation (better)
Deadline Propagation:
- Original caller sets an absolute deadline (e.g., "must complete by T+2s")
- Each service checks remaining time before making downstream calls
- Prevents a 2s timeout at each level from becoming 6s end-to-end
Payment System Fault Tolerance
Multi-Layer Fault Tolerance:
- Transport Layer: TCP connections with keepalive, connection pooling
- Application Layer: Circuit breakers, retries, bulkheads
- Data Layer: Replication, backup, WAL (Write-Ahead Log)
- Infrastructure Layer: Multi-AZ deployment, auto-scaling, health checks
- Business Layer: Idempotency, compensation transactions (saga pattern)
Saga Pattern for Payment:
Order Service: CreateOrder → ReserveInventory → ProcessPayment → ConfirmOrder
Failure at Payment: CreateOrder → ReserveInventory → ProcessPayment (FAIL)
Compensation: CancelOrder ← ReleaseInventory ← RefundPayment ← (triggered)
- Each step has a corresponding compensating transaction
- If any step fails, all previous steps are compensated
- Ensures system returns to a consistent state
Disaster Recovery
RPO and RTO
RPO (Recovery Point Objective):
- Maximum acceptable data loss measured in time
- "We can afford to lose at most 1 hour of data" → RPO = 1 hour
- Determines backup frequency
- RPO = 0 means no data loss (synchronous replication)
RTO (Recovery Time Objective):
- Maximum acceptable time to restore service after a disaster
- "Service must be restored within 4 hours" → RTO = 4 hours
- Determines failover automation level
| Strategy | RPO | RTO | Cost |
|---|---|---|---|
| Backup & Restore | Hours | Hours to Days | Low |
| Pilot Light | Minutes | 10-60 minutes | Medium |
| Warm Standby | Seconds | Minutes | High |
| Active-Active | 0 (near) | Seconds | Very High |
Backup and Restore
- RPO: Hours (depends on backup frequency)
- RTO: Hours to days
- Process: Regular backups to secondary region, restore when disaster occurs
- Cheapest option but slowest recovery
Amazon Implementation:
- EBS snapshots to S3 cross-region
- RDS automated backups with point-in-time recovery
- S3 cross-region replication
- DynamoDB point-in-time recovery + on-demand backups
Pilot Light
- RPO: Minutes
- RTO: 10-60 minutes
- Core infrastructure is running in DR region but at minimal capacity
- Data is replicated continuously
- On failover: scale up DR infrastructure to full capacity
Example:
- Primary region: Full application stack
- DR region: Database replica + minimal compute (one small instance)
- On failover: Scale compute, update DNS, promote DB replica
Warm Standby
- RPO: Seconds
- RTO: Minutes
- DR region runs a scaled-down copy of production
- On failover: Scale up to full capacity
Example:
- Primary region: 10 instances
- DR region: 2 instances (20% capacity)
- On failover: Scale DR to 10 instances, redirect traffic
Active-Active (Multi-Region)
- RPO: ~0
- RTO: Seconds (automated)
- Both regions handle production traffic simultaneously
- Global load balancer (Route 53, CloudFront) routes to nearest region
- Data conflicts resolved via CRDTs or last-writer-wins
Amazon Implementation:
- Route 53 latency-based or geolocation routing
- DynamoDB Global Tables (multi-master replication)
- Aurora Global Database (1-second replication lag)
- ElastiCache Global Datastore
Disaster Recovery Testing
Tabletop Exercises:
- Walk through disaster scenarios on paper
- Identify gaps in runbooks and procedures
- Low cost, high value
Game Days:
- Simulate real failures in production-like environment
- Test actual failover procedures
- Measure actual RPO and RTO
Chaos Engineering in DR Context:
- Kill an entire AZ to test cross-AZ failover
- Simulate region failure for multi-region systems
- Verify monitoring and alerting triggers correctly
Multi-Region Failover Architecture
┌─────────────────────┐
│ Route 53 (Global) │
│ Latency-based │
│ Routing │
└──────────┬──────────┘
│
┌────────────────┼────────────────┐
│ │ │
┌─────────▼─────────┐ ┌───▼───────────┐ ┌──▼──────────────┐
│ US-EAST-1 │ │ EU-WEST-1 │ │ AP-SOUTHEAST-1 │
│ (Primary) │ │ (Secondary) │ │ (Secondary) │
│ │ │ │ │ │
│ ┌─────────────┐ │ │ ┌───────────┐ │ │ ┌─────────────┐ │
│ │ App Servers │ │ │ │ App │ │ │ │ App Servers │ │
│ │ (Auto Scale)│ │ │ │ Servers │ │ │ │ (Auto Scale)│ │
│ └──────┬──────┘ │ │ └─────┬─────┘ │ │ └──────┬──────┘ │
│ │ │ │ │ │ │ │ │
│ ┌──────▼──────┐ │ │ ┌─────▼─────┐ │ │ ┌──────▼──────┐ │
│ │ Aurora │←─┼─┤►│ Aurora │←─┼─┤►│ Aurora │ │
│ │ Primary │──┼─┼─│ Read │──┼─┼─│ Read │ │
│ │ │ │ │ │ Replica │ │ │ │ Replica │ │
│ └─────────────┘ │ │ └───────────┘ │ │ └────────────┘ │
└───────────────────┘ └───────────────┘ └────────────────┘
Failover: Route 53 health check fails → remove from DNS → traffic shifts to nearest healthy region → Aurora replica promoted to primary
Failover Procedure:
- Route 53 health check detects primary region failure
- DNS record updated to remove primary region (TTL: 60s)
- Traffic shifts to secondary region within 60 seconds
- Aurora read replica promoted to primary (automatic or manual)
- Application continues serving from secondary region
- When primary recovers: rebuild as replica, then fail back
Amazon-Specific DR Services
| Service | DR Feature | RPO | RTO |
|---|---|---|---|
| RDS | Multi-AZ | 0 | 1-2 min |
| Aurora | Global Database | 1 sec | 1 min |
| DynamoDB | Global Tables | ~0 | seconds |
| S3 | Cross-Region Replication | minutes | N/A |
| ElastiCache | Global Datastore | seconds | minutes |
| Route 53 | Health checks + failover | N/A | seconds |
| CloudFront | Origin failover | N/A | seconds |
| EBS | Cross-region snapshots | hours | hours |
| EC2 | Auto Scaling + Multi-AZ | N/A | minutes |
Practice Problems
Design a scalable Reliability system. Cover high-level architecture, data model, and API design.
Solution
// Complete system design:
// - Functional + Non-functional requirements
// - Capacity estimation
// - Data model (SQL/NoSQL choice)
// - API endpoints
// - Component architecture
// - Scaling strategy
// - Monitoring & reliabilityHow would you scale Reliability to handle 10x the current load? Identify bottlenecks and solutions.
Solution
// Scaling approach:
// 1. Load balancing
// 2. Database sharding/replication
// 3. Cache layer (Redis)
// 4. CDN for static assets
// 5. Async processing (queues)
// 6. Microservices decompositionAnalyze potential failure modes for Reliability and design mitigation strategies.
Solution
// Failure mitigation:
// 1. Redundancy (multi-AZ)
// 2. Circuit breakers
// 3. Retry with backoff
// 4. Dead letter queues
// 5. Health checks
// 6. Graceful degradationQuiz
1. Your SLI shows 99.95% availability over 30 days. Your SLO is 99.9%. What does this mean?
2. A circuit breaker is in the OPEN state. A new request arrives. What happens?
3. Why do we add jitter to exponential backoff retries?
4. What is the RPO of an active-active multi-region system with synchronous replication?
5. In a 5-node cluster using Raft consensus, how many nodes must agree for a decision to be committed?
6. Which disaster recovery strategy has the lowest RPO and RTO but the highest cost?
7. What is the primary purpose of the bulkhead pattern?
8. What does a Phi Accrual Failure Detector output?
Flashcards
Question
What is the difference between SLA, SLO, and SLI?
Click to reveal answer
Answer
SLI (Service Level Indicator) is a quantitative metric (e.g., 99.9% availability). SLO (Service Level Objective) is an internal target for the SLI (e.g., maintain 99.9% availability over 30 days). SLA (Service Level Agreement) is a contractual commitment with customers that includes the SLO plus consequences for missing it (e.g., service credits).
Question
What are the three states of a circuit breaker?
Click to reveal answer
Answer
1) Closed: Normal operation, requests pass through, failures are counted. When failure threshold is exceeded → Open. 2) Open: Fails fast, rejects all requests without calling dependency. After timeout → Half-Open. 3) Half-Open: Allows limited test requests. If they succeed → Closed. If they fail → Open.
Question
What is an error budget and why is it important?
Click to reveal answer
Answer
Error budget = 1 - SLO. If SLO is 99.9%, the error budget is 0.1% (about 43 minutes per month). It represents how much unreliability is acceptable. When the error budget is consumed, feature releases are frozen until it resets. This prevents velocity pressure from eroding reliability.
Question
What is the difference between RPO and RTO?
Click to reveal answer
Answer
RPO (Recovery Point Objective) is the maximum acceptable data loss measured in time — how far back in time you can lose data. RTO (Recovery Time Objective) is the maximum acceptable downtime — how quickly you must restore service. RPO determines backup frequency; RTO determines automation level of failover.
Question
Explain the four disaster recovery strategies from lowest to highest cost.
Click to reveal answer
Answer
1) Backup & Restore: Backups in DR region, restore on disaster (low cost, hours RTO). 2) Pilot Light: Core infra running minimally in DR, scale up on failover (medium cost, 10-60 min RTO). 3) Warm Standby: Scaled-down copy in DR, scale to full on failover (high cost, minutes RTO). 4) Active-Active: Full production in multiple regions (very high cost, seconds RTO).
Question
What is the bulkhead pattern and when would you use it?
Click to reveal answer
Answer
The bulkhead pattern isolates resources per dependency (thread pools, connection pools, semaphores) so a failure in one dependency cannot exhaust all resources for others. Use it when you have multiple downstream dependencies where a slow or failing one could block all requests. Example: Separate thread pools for database, cache, and external API calls.
Question
What is active-active vs active-passive redundancy?
Click to reveal answer
Answer
Active-Active: All instances serve traffic simultaneously. Pros: max throughput, no failover delay. Cons: data consistency complexity (conflict resolution needed). Active-Passive: One primary handles traffic, others are standby replicas. Pros: simpler data sync. Cons: standby resources are wasted, failover takes longer.
Question
What is chaos engineering and what is Chaos Monkey?
Click to reveal answer
Answer
Chaos engineering proactively introduces failures to discover weaknesses before they cause outages. Chaos Monkey (Netflix) randomly terminates production instances during business hours to force engineers to build resilient systems. Part of Netflix's Simian Army. Key principles: build hypothesis about steady-state, vary real-world events, run in production, automate, minimize blast radius.
Revision Notes
Key Takeaways
- 1.Always define SLIs before SLOs, and SLOs before SLAs — they form a hierarchy
- 2.Error budgets balance velocity with reliability — when budget is spent, stop deploying
- 3.Circuit breakers prevent cascading failures; combine with retries and bulkheads for robust resilience
- 4.RPO = how much data you can lose; RTO = how long you can be down — both drive architecture cost
- 5.Chaos engineering is proactive — inject failures to find weaknesses before production incidents
- 6.For payment systems: idempotency + circuit breakers + dual providers + saga compensation
- 7.Active-active provides best RPO/RTO but requires conflict resolution strategy for writes
Interview Tips
- •Start every reliability discussion by asking about SLA requirements — it drives all design decisions
- •When asked about reliability, mention the full stack: infrastructure, application, data, and business layers
- •Calculate error budgets explicitly: '99.9% uptime means 8.76 hours downtime per year — our error budget is about 43 minutes per month'
- •For disaster recovery, ask about RPO/RTO requirements before proposing a solution — different requirements mean very different architectures
- •Mention trade-offs: active-active is expensive but has best RPO/RTO; active-passive saves money but has slower failover
- •Always discuss monitoring and alerting — you can't manage what you can't measure
- •When discussing circuit breakers, mention the fallback strategy — what happens when the circuit is open?
Cheat Sheet
Reliability Cheat Sheet
Metrics
- SLI: Quantitative measure (latency, throughput, error rate, availability)
- SLO: Internal target for SLI (e.g., 99.9% availability over 30 days)
- SLA: Contractual commitment = SLO + consequences
- Error Budget: 1 - SLO. Consume = freeze features.
Redundancy
- Active-Active: All nodes serve traffic. Max throughput. Complex consistency.
- Active-Passive: Primary + standby. Simpler. Wasted standby resources.
- N+1: N active + 1 spare. Balanced cost/reliancy.
Patterns
- Circuit Breaker: Closed → Open → Half-Open. Prevents cascading failures.
- Retry + Backoff: Exponential backoff + jitter. Only retry idempotent ops.
- Bulkhead: Isolate resources per dependency. Thread pools, connection pools.
Fault Tolerance
- Graceful degradation: Reduce functionality, don't fail entirely.
- Health checks: Liveness (restart), Readiness (remove from LB), Startup.
- Failure detection: Heartbeats, Gossip protocol, Phi Accrual detector.
- Consensus: Quorum = N/2 + 1. Raft (leader election + log replication).
Disaster Recovery
- RPO: Max data loss (time). RTO: Max downtime (time).
- Backup & Restore: Low cost, hours RTO
- Pilot Light: Medium cost, 10-60 min RTO
- Warm Standby: High cost, minutes RTO
- Active-Active: Very high cost, seconds RTO
Payment System Pattern
- Idempotency keys for retries
- Circuit breaker on payment gateway
- Dual providers (Stripe + PayPal)
- Transactional outbox for exactly-once processing
- Saga pattern for compensation