4 · High Availability & Fault Tolerance¶
Domain 2 — Design Resilient Architectures · 26%
The core exam skill here is recognizing single points of failure and removing them with the standard AWS pattern: spread across Availability Zones, put an ELB in front, and let an Auto Scaling group replace what breaks. Most questions reduce to "which load balancer?" and "which scaling policy / health check?"
Core concept¶
High availability (HA) = the system keeps serving through a component or AZ failure. Fault tolerance = it does so with no loss of service. In AWS you build both by removing single points of failure:
- Run in multiple Availability Zones (independent data centers, low-latency linked). One AZ dying shouldn't take you down.
- Put an Elastic Load Balancer in front to spread traffic and stop routing to unhealthy targets.
- Wrap compute in an Auto Scaling group (ASG) so failed instances are replaced automatically and capacity follows demand.
The canonical resilient web tier: ALB → ASG spanning ≥ 2 AZs. Commit that shape to memory — it's the correct answer to a large family of questions.
AZ vs Region
Multi-AZ protects against a data-center/AZ failure and is the default HA unit. Multi-Region protects against a whole-Region failure and is a disaster recovery concern (Topic 6) — more complex and costly, chosen only when the requirement is Region-level resilience or global latency.
Elastic Load Balancing — which one?¶
| Load balancer | Layer | Use when | Key traits |
|---|---|---|---|
| Application (ALB) | 7 (HTTP/HTTPS) | Web apps, microservices, containers | Host/path routing, redirects, WAF, targets = EC2/IP/Lambda/containers, user auth |
| Network (NLB) | 4 (TCP/UDP/TLS) | Extreme performance, static IP, low latency | Millions of req/s, ultra-low latency, static/Elastic IP per AZ, preserves source IP |
| Gateway (GLB) | 3 | Deploy third-party virtual appliances (firewalls, IDS/IPS) | Transparent inline traffic inspection (GENEVE) |
| Classic (CLB) | legacy | — | Deprecated; don't choose it for new designs |
Signal words: path/host routing or Lambda targets → ALB; static IP / millions of connections / raw TCP/UDP / lowest latency → NLB; inline firewall appliance → GLB.
Features that show up as answers:
- Health checks — the ELB stops sending traffic to targets that fail checks.
- Cross-zone load balancing — spreads requests evenly across targets in all AZs. On by default and free on ALB; off by default on NLB (and enabling it can incur inter-AZ data charges).
- Connection draining / deregistration delay — lets in-flight requests finish before an instance is removed.
- Sticky sessions (session affinity) — pins a user to one target (needed for non–stateless apps).
- TLS termination + SNI — offload HTTPS at the ELB; SNI serves many certs on one listener.
Auto Scaling groups¶
An ASG keeps the number of healthy instances between min and max, targeting desired capacity, using a launch template (which AMI/type/SG/role to launch). Two jobs:
- Self-healing — if an instance fails its health check, the ASG terminates and replaces it.
- Elasticity — it scales out/in on demand via a scaling policy:
| Policy | Use when |
|---|---|
| Target tracking | Simplest and most common — "keep average CPU at 50%." Start here. |
| Step scaling | Add/remove capacity in steps based on alarm magnitude |
| Simple scaling | One adjustment per alarm (older; step scaling is usually better) |
| Scheduled scaling | Known time-based patterns (e.g. scale up every weekday 9am) |
| Predictive scaling | ML forecasts load and scales ahead of it |
Health check type is a classic gotcha. By default an ASG uses EC2 status checks — which only confirm the instance/OS is running. If your application has hung but the OS is fine, the ASG won't notice. Behind a load balancer, switch the ASG to ELB health checks so an instance the ELB considers unhealthy is replaced. Pair this with a proper application health-check endpoint.
Worked example — the "healthy" but broken instances¶
A web app runs on an ASG behind an ALB across two AZs. The app process crashes on several instances, but the instances themselves keep running. The ALB returns errors from those instances, yet the ASG never replaces them. Users see intermittent failures.
Why, and what's the fix?
Answer
The ASG is using the default EC2 health check, which only verifies the instance/OS is running — and it is. It has no idea the application died. Meanwhile the ALB's health check (hitting an HTTP endpoint) marks those targets unhealthy and stops routing to them, but the ASG doesn't act on the ALB's opinion unless you tell it to. Fix: set the ASG's health check type to ELB so it replaces instances the ALB reports as unhealthy, and make sure the ALB health check targets a real application endpoint (not just a TCP port). Now broken instances are terminated and replaced.
Exam traps¶
- The resilient default is ALB + ASG across ≥ 2 AZs — a single instance, or everything in one AZ, is a single point of failure.
- ASG default health check is EC2-only → behind an ELB, switch to ELB health checks or app crashes go unnoticed.
- Static IP / raw TCP/UDP / extreme performance → NLB; HTTP routing / Lambda targets → ALB.
- Cross-zone LB is on+free for ALB, off by default for NLB (and may add inter-AZ transfer cost).
- Target tracking is the go-to scaling policy; reach for scheduled/predictive only when the pattern is time-based/forecastable.
- An ASG doesn't add HA by itself — it must span multiple AZs; min ≥ 2 across AZs for true HA.
- Load balancers and ASGs are Regional constructs (multi-AZ), not multi-Region.
Practice questions¶
Q1. A web application must stay available even if an entire Availability Zone fails, and capacity should follow demand automatically. Which design?
- A. A large EC2 instance in one AZ with a backup AMI.
- B. An Auto Scaling group spanning two AZs behind an Application Load Balancer.
- C. Two EC2 instances in the same AZ behind an ALB.
- D. An NLB pointing at one instance per AZ with manual scaling.
Answer: B
B. An ASG across two AZs behind an ALB survives an AZ failure, replaces unhealthy instances, and scales automatically. A and C keep a single point of failure (one AZ). D lacks automatic scaling and self-healing.
Q2. An application needs a load balancer that provides a static IP address and can handle millions of requests per second of raw TCP traffic with ultra-low latency. Which should be used?
- A. Application Load Balancer
- B. Network Load Balancer
- C. Gateway Load Balancer
- D. Classic Load Balancer
Answer: B
B. The NLB operates at Layer 4, delivers extreme performance and low latency, and provides a static IP (or Elastic IP) per AZ. The ALB (A) is HTTP-layer with no static IP. GLB (C) is for inline virtual appliances. CLB (D) is legacy.
Q3. Instances in an Auto Scaling group behind an ALB keep serving errors after the application process crashes, but the ASG never replaces them. What is the most likely cause?
- A. The ALB has no listener.
- B. The ASG is using EC2 status checks instead of ELB health checks.
- C. Cross-zone load balancing is disabled.
- D. The launch template has the wrong AMI.
Answer: B
B. EC2 status checks only confirm the OS is running, so an app crash goes undetected. Switching the ASG's health check type to ELB lets it replace instances the ALB marks unhealthy. The other options wouldn't produce "running but serving errors and never replaced."
Q4. A retailer knows traffic spikes every weekday at 8am when a promotion goes live, and is flat otherwise. What is the most efficient scaling approach?
- A. Target tracking on CPU only
- B. Scheduled scaling to add capacity before 8am, plus target tracking for the rest
- C. Manually resize instances each morning
- D. Provision peak capacity 24/7
Answer: B
B. The spike is time-predictable, so scheduled scaling pre-warms capacity before 8am, while target tracking handles everything else. Target tracking alone (A) reacts after load rises, risking a slow start. Manual resizing (C) is error-prone; running peak capacity always (D) wastes money.
Q5. A stateful application stores session data in each instance's memory. When placed behind a load balancer, users are randomly logged out. What is the simplest fix (assuming the app can't be made stateless immediately)?
- A. Enable sticky sessions on the load balancer.
- B. Switch to a Network Load Balancer.
- C. Increase the health check interval.
- D. Disable cross-zone load balancing.
Answer: A
A. Sticky sessions (session affinity) pin each user to the same target so their in-memory session persists. The real long-term fix is externalizing session state (e.g. to ElastiCache/ DynamoDB), but the question asks for the simplest immediate fix. B, C, and D don't address session affinity.
Next: 5 · Database Resilience → · Revise — HA & Fault Tolerance