How do an Auto Scaling group and a load balancer work together on AWS?
An Auto Scaling group keeps the right number of healthy EC2 instances running, adding or removing them based on policies such as target CPU. A load balancer spreads incoming traffic across those instances in multiple AZs. The ASG registers new instances with the load balancer's target group and replaces any that fail health checks.
Explain it simply
Think of a railway reservation counter during the Tatkal window. The load balancer is the person at the entrance telling each passenger which counter is free. The Auto Scaling group is the station manager watching the queue. When the queue grows, the manager opens more counters. When it is quiet in the afternoon, counters close. If a clerk falls sick, the manager puts someone else at that counter, and the person at the entrance stops sending passengers there until it is staffed again.
Together they give you two things: the app survives failures, and you pay only for the capacity you need right now.
Example
Launch template: AMI with the app, instance type, app-sg, IAM role
Auto Scaling group "web-asg"
Subnets: private subnets in AZ a, b, c
Min: 2 Desired: 3 Max: 12
Health check type: ELB
Scaling policy: target tracking, average CPU = 50%
Attached to target group "web-tg"
Application Load Balancer (public subnets in a, b, c)
Listener HTTPS :443 -> forward to "web-tg"
Health check: GET /health every 30s, expect 200
Sale starts:
CPU rises to 80% -> ASG launches more instances
New instances boot, pass /health -> ALB starts sending traffic
Night:
CPU falls to 20% -> ASG terminates extra instances (never below 2)How it works
Auto Scaling group (ASG)
- Uses a launch template that describes each instance: AMI, instance type, security groups, IAM role and user data.
- Has minimum, desired and maximum capacity. It always tries to keep the desired count running, within min and max.
- Spreads instances across the subnets (and so AZs) you give it, and rebalances if one AZ ends up with too many.
- Scaling policies: target tracking (keep a metric like average CPU or requests per target near a value), step scaling (add N instances when an alarm crosses a threshold), scheduled scaling (add capacity before a known event), and predictive scaling (forecast from past daily or weekly patterns).
- Health checks: with EC2 checks, only instance-level failures count. With ELB checks enabled, an instance the load balancer marks unhealthy is also replaced.
Load balancer (Elastic Load Balancing)
- Application Load Balancer works at layer 7 (HTTP/HTTPS): routes by path or host, terminates TLS.
- Network Load Balancer works at layer 4 (TCP/UDP/TLS): very high throughput, static IP per AZ.
- Sends traffic only to targets that pass its health check.
The handshake between them: the ASG is attached to a target group. Every instance it launches is registered in that group; every instance it terminates is first deregistered, and connection draining (deregistration delay) lets in-flight requests finish before the instance goes away.
Real-world use
E-commerce sites before a big sale, exam-result portals on result day and ticketing apps during a popular concert all follow this pattern. Teams often add scheduled scaling an hour before the known spike, because new instances take minutes to boot and pass health checks, and target tracking alone reacts after the load arrives.
Common mistakes
- Storing sessions or uploaded files on the instance's local disk. When the ASG terminates it, the data is gone. Keep servers stateless and use a shared store such as ElastiCache, DynamoDB or S3.
- Leaving the ASG on EC2 health checks only, so an instance whose app has crashed but whose VM is fine keeps receiving traffic.
- A
/healthendpoint that checks the database. If the database blips, every instance fails health checks and the ASG replaces them all at once. - Setting max capacity too low, or forgetting account-level instance quotas before a big event.
- Using a single AZ for the ASG, so one AZ failure takes everything down.
What to say in the interview
"The load balancer, usually an ALB for HTTP, sits in public subnets across multiple AZs and distributes requests to a target group, sending traffic only to instances that pass health checks. The Auto Scaling group, built from a launch template, keeps a desired number of instances between a min and max across those AZs, registers new ones in the target group, and replaces unhealthy ones, using ELB health checks. I'd use target tracking on CPU or requests per target, add scheduled scaling for known spikes, keep instances stateless, and rely on connection draining so scale-in doesn't drop requests."
Follow-up questions
- Why must instances behind an ASG be stateless?
- What is the difference between target tracking and step scaling?
- How do warm-up time and cooldown affect scaling?
- When would you pick an NLB over an ALB?
- How would you roll out a new app version with zero downtime?
Go deeper
Read these once the basics above feel easy.
New instances need time to boot and warm up; configure instance warm-up so their early metrics do not trigger more scaling. Baking the app into the AMI starts instances faster than installing everything in user data. Requests per target is often a better scaling metric than CPU for web apps. Warm pools keep pre-initialised stopped instances ready for faster scale-out.
Use instance refresh or a blue/green deployment (a second target group, then shift ALB traffic) to release new versions safely. Mix On-Demand and Spot capacity with multiple instance types in a mixed instances policy to cut cost while staying resilient to Spot interruptions. Lifecycle hooks let you run scripts on launch or before termination, for example to flush logs. Remember that the ASG can only scale as fast as dependencies allow; a single database often becomes the real bottleneck during a spike.