intermediate~2.5h

Auto Scaling & Elastic Load Balancing

Automatically matching EC2 capacity to real demand, and distributing traffic across that capacity so no single instance is a bottleneck or a single point of failure.

Want a visual for this topic?

Generate a diagram tailored to Auto Scaling & Elastic Load Balancing — the AI picks whichever visual (architecture, flowchart, ER diagram, etc.) best fits this specific AWS concept.

Sign in to generate a visual →
2
Subtopics

🎓 Learning objectives

  • Explain the relationship between a Launch Template, an Auto Scaling Group, and a Load Balancer
  • Choose between ALB, NLB, and GWLB for a given use case
  • Configure a target-tracking Auto Scaling policy
  • Explain how health checks let an Auto Scaling Group self-heal

What is it?

EC2 Auto Scaling automatically launches or terminates EC2 instances to match a target defined by you (a minimum/maximum/desired count, and optionally a scaling policy tied to a metric), while Elastic Load Balancing (ELB) distributes incoming traffic across all the healthy instances in that fleet — together they turn a group of individual servers into one self-healing, elastically-sized service.

Why it exists

A single EC2 instance is a single point of failure (if it crashes, your service is down) and a fixed-capacity ceiling (it can only handle so much traffic before it's saturated). Running multiple instances solves both problems, but only if traffic is distributed across them (otherwise it doesn't help), unhealthy instances are automatically replaced (otherwise someone has to notice and fix it manually), and the number of instances adjusts to actual demand (otherwise you're either overpaying for idle capacity or under-provisioned during a spike).

Problem it solves

It solves the single-point-of-failure problem (an unhealthy instance is automatically detected and replaced), the traffic-distribution problem (a load balancer ensures no single instance gets overwhelmed while others sit idle), and the capacity-matching problem (Auto Scaling adds instances under load and removes them when load drops, controlling both availability and cost).

Intuition

Think of a restaurant during a sudden dinner rush: instead of one waiter (a single EC2 instance) trying to serve every table and inevitably falling behind, the host (the Load Balancer) seats new customers at whichever open table has a waiter free, and the manager (Auto Scaling) calls in more waiters from the back when the restaurant gets busy, sending them home again once it quiets down — no single waiter is a bottleneck, and the staffing level tracks actual demand instead of always running at max headcount.

Analogy

A call center with a rotating dispatcher: incoming calls (traffic) are routed by the dispatcher (Load Balancer) to whichever available agent (healthy EC2 instance) is free; if an agent stops responding to test pings (fails a health check), the dispatcher stops sending them calls and the staffing system automatically brings in a replacement; during a promotional event, the staffing system (Auto Scaling policy) brings on more agents ahead of time based on the predicted call volume.

Technical explanation

A Launch Template defines everything needed to launch a new instance (AMI, instance type, Security Group, IAM Role, User Data script) so the Auto Scaling Group can create identical instances on demand without manual intervention. Target-tracking scaling policies (the most common type) let you specify a target value for a metric (e.g. 'keep average CPU at 50%') and AWS's scaling algorithm automatically calculates how many instances are needed to hit that target, adding or removing instances as needed — this is generally preferred over manually-tuned step-scaling policies for its simplicity. Health checks come in two forms: EC2 status checks (does the instance respond at all) and, more usefully, Load Balancer health checks (does the application on that instance respond correctly to a specific health-check path, e.g. GET /health returning 200) — an instance failing either type is marked unhealthy, removed from the load balancer's rotation, and (for Auto Scaling Group-managed instances) automatically terminated and replaced.

Architecture

Application Load Balancer (ALB) operates at Layer 7 (HTTP/HTTPS) and can route based on URL path or hostname (e.g. /api/* to one target group, /images/* to another) — the right choice for most modern web applications and microservices. Network Load Balancer (NLB) operates at Layer 4 (TCP/UDP), handling extreme throughput and preserving the client's source IP, used for latency-sensitive or non-HTTP protocols. Gateway Load Balancer (GWLB) is a more specialized option for transparently inserting third-party network appliances (firewalls, intrusion detection) into a traffic path. Most standard web/API workloads use an ALB in front of an Auto Scaling Group spanning multiple Availability Zones.

Workflow

  1. Create a Launch Template defining the instance configuration. 2) Create a Target Group (the set of instances a load balancer routes to, along with the health check configuration). 3) Create the Load Balancer (typically ALB) pointing at that Target Group, spanning multiple AZs. 4) Create the Auto Scaling Group using the Launch Template, attach it to the Target Group so new instances are automatically registered, set min/max/desired counts spread across multiple AZs, and attach a target-tracking scaling policy. 5) Point your DNS (Route 53) at the Load Balancer's stable DNS name, never at individual instance IPs.

Example

An e-commerce site's Auto Scaling Group is configured with min=2, max=20, desired=4, target-tracking on 60% average CPU, spread across 3 AZs, behind an ALB. During a flash sale, CPU utilization climbs past 60% and the group scales out to 12 instances within a few minutes; overnight, with almost no traffic, it scales back down toward the minimum of 2, saving cost automatically without anyone manually intervening in either direction.

Real-world usage

This Load Balancer + Auto Scaling Group pattern is the single most common production web architecture on AWS and is explicitly the reference architecture in AWS's own well-architected examples; companies handling highly variable traffic (e-commerce around sales events, media sites around breaking news, ticketing platforms around on-sale moments) rely on exactly this combination to absorb spikes automatically rather than pre-provisioning for worst-case load year-round.

Trade-offs

A single EC2 instance is simpler to reason about and cheaper for genuinely low-stakes, low-traffic workloads (a personal project, an internal tool with a handful of users), but has no fault tolerance and no ability to absorb a traffic spike gracefully. An Auto Scaling Group behind a Load Balancer adds real complexity and baseline cost (a minimum of at least 2 instances plus the load balancer itself, even at idle) but is close to mandatory for anything customer-facing or business-critical, where downtime or an inability to handle a spike has a real cost that outweighs the added infrastructure.

Visual explanation

Picture three layers stacked: at the top, a Load Balancer (with a single stable DNS name your users/DNS records point to) receiving all incoming traffic. Below it, an Auto Scaling Group — a logical container defining min/max/desired instance count and a Launch Template (the AMI, instance type, and configuration every new instance should use). Inside the Auto Scaling Group, individual EC2 instances come and go over time as the group scales; the Load Balancer continuously health-checks each one and only routes traffic to the ones currently passing.

Advantages

  • Self-healing — an unhealthy instance is automatically detected and replaced with no manual intervention

  • Cost efficiency — capacity tracks actual demand instead of being fixed at a guessed peak

  • High availability — spreading instances and the load balancer across multiple AZs survives a data-center-level failure

  • Decouples 'how many instances exist' from 'where do users connect' — the load balancer's DNS name never changes even as instances are replaced

Disadvantages

  • New instances take real time (often 1-5 minutes) to boot and pass health checks, so reactive scaling always lags a sudden spike somewhat

  • Misconfigured health checks (checking the wrong path, too aggressive thresholds) can cause a scaling/termination flapping loop or mask a real outage as 'healthy'

  • More moving parts (Launch Template, Target Group, ASG, Load Balancer, scaling policy) than a single instance, adding operational complexity and more places to misconfigure

  • Load Balancers and NAT Gateways have their own hourly + data-processing costs on top of the EC2 instances themselves

Common mistakes

  • Setting a health check path that doesn't actually verify the application is working (e.g. checking a static file that's served even if the app's database connection is broken) — the load balancer keeps sending traffic to a technically-broken instance

  • Setting min=max=desired to the same fixed number, defeating the entire purpose of Auto Scaling — this is really just a fixed-size fleet with automatic replacement of failed instances, not true elasticity

  • Not spreading Auto Scaling Group instances and the Load Balancer across multiple AZs, recreating a single point of failure at the AZ level

  • Scaling policies with too-short a cooldown period, causing instances to launch and terminate rapidly (thrashing) before new instances have even finished booting and stabilizing

In the AWS Console

  1. 1

    EC2 → Launch Templates → Create launch template

    Define the AMI, instance type, Security Group, IAM Role, and User Data script that every future instance in the group should use.

    Version your Launch Templates (AWS does this automatically on each edit) so you can roll back to a previous known-good configuration if a new version causes issues.

  2. 2

    EC2 → Target Groups → Create target group

    Choose 'Instances' as the target type, configure the health check path (e.g. /health) and thresholds, matching what your application actually serves.

    Test the health check path manually first (curl it) — a wrong path here silently marks every instance unhealthy and the load balancer returns 503s for everyone.

  3. 3

    EC2 → Load Balancers → Create Load Balancer → Application Load Balancer

    Select at least 2 (ideally all available) Availability Zones, attach a listener (e.g. HTTPS:443) that forwards to the Target Group created above.

    For HTTPS, you'll need an ACM (AWS Certificate Manager) certificate attached to the listener — ACM certificates for this use case are free.

  4. 4

    EC2 → Auto Scaling Groups → Create Auto Scaling group

    Select the Launch Template, choose the VPC and multiple subnets (one per AZ) to spread across, attach the existing Target Group, and set min/max/desired capacity.

    Attaching the Target Group here is what makes new instances automatically register with the load balancer — a step that's easy to miss.

  5. 5

    Auto Scaling Groups → [your group] → Automatic scaling → Create dynamic scaling policy

    Choose 'Target tracking scaling policy', select a metric (e.g. Average CPU Utilization), and set a target value (e.g. 50%).

    Target tracking is the recommended default — it self-tunes how many instances to add/remove to hit the target, instead of you hand-tuning step thresholds.

🎤 Interview questions

Explain how a Launch Template, an Auto Scaling Group, and a Load Balancer relate to each other. (Listen for: Launch Template defines instance config; ASG uses it to launch/terminate instances to match capacity targets; Load Balancer distributes traffic across the ASG's healthy instances and is what users/DNS actually point to.)

When would you choose a Network Load Balancer over an Application Load Balancer? (Listen for: NLB for Layer 4/TCP-UDP, extreme throughput, preserving client source IP, non-HTTP protocols; ALB for Layer 7/HTTP routing by path or host.)

How does an Auto Scaling Group know an instance is unhealthy and needs replacing? (Listen for: EC2 status checks and/or Load Balancer health checks against a specific path; failing instances are deregistered from the load balancer and terminated/replaced.)

Why does reactive auto-scaling still cause brief performance degradation during a sudden traffic spike? (Listen for: new instances take real time to boot, initialize, and pass health checks before they can absorb load — the scaling response always lags the spike by that boot time.)

What's wrong with setting an Auto Scaling Group's min, max, and desired capacity to the same value? (Listen for: that removes true elasticity — it becomes a fixed-size fleet with self-healing but no ability to scale with actual demand.)

📂 Subtopics

💬 Deep Dive with AI

Related concepts

ec2-fundamentalsec2-security-networkingaws-well-architected-framework

Next Step

Continue to AWS Lambda & Serverless