EC2 Auto Scaling Group
A managed fleet of EC2 instances that AWS keeps at the size you asked for — replacing what fails and spreading across Availability Zones. Here's why availability matters more than elasticity, what it actually costs, and the scaling mistakes Design Beaver catches as you draw.
What an Auto Scaling group is
An Auto Scaling group is a managed collection of EC2 instances that AWS keeps at the size you asked for. You give it three numbers — minimum, maximum, and desired capacity — a launch template describing what an instance should look like, and a set of subnets to launch into. From then on it launches instances when load rises, terminates them when load falls, and replaces any instance that fails a health check.
Two things get conflated here, and separating them changes how you design. Scaling is the elasticity story: match capacity to demand, stop paying for idle servers. Self-healing and zone redundancy is the availability story: an instance dies and the group replaces it; a zone dies and the group still has instances elsewhere. The second is usually the bigger win, and you get it even with completely flat traffic. Two instances across two zones at min=2, max=2 does no scaling at all and is still far more available than one instance.
Design Beaver models an Auto Scaling group as a container — a dashed boundary that owns EC2 nodes — rather than a service block, because a real group spans subnets and Availability Zones and a single-parent node can’t express that. It validates as you draw that the instances inside it are actually spread the way you think they are.
When to use an Auto Scaling group (and when not to)
Use one any time more than one instance is doing the same job, and especially when the workload has to survive an instance failure or a whole zone going down. If traffic varies enough that a fixed fleet either wastes money idle or falls over at peak, that’s the elasticity case. If you’d rather not have someone reading an alarm at 3am to replace a box, that’s the self-healing case.
Skip it when the compute service already scales for you — Lambda, Fargate, and App Runner have no fleet to size, and adding a scaling concept on top invents a problem. Skip it for a genuinely un-replaceable stateful instance, like a legacy licence pinned to one host. And if your capacity is fixed, predictable, and already committed to Reserved Instances for exactly that shape, a group buys you self-healing but no savings.
Variants: scaling policy types
The variants here aren’t editions of a product. They’re the policy types you choose between when you create the group, and picking the wrong one is how groups end up reacting too late.
| Option | What it is |
|---|---|
| Target trackingdefault | Pick a metric and a target value (e.g. 50% average CPU) and the group holds it, like a thermostat. AWS creates and manages the backing CloudWatch alarms. The recommended default for most workloads. |
| Step scaling | Adjusts capacity by different amounts depending on how far the metric has breached the alarm threshold. More control than simple scaling, for when one adjustment size doesn't fit every breach. |
| Simple scaling | A single capacity adjustment per alarm, with a cooldown before the next scaling activity. The oldest policy type; generally superseded by target tracking or step scaling. |
| Scheduled scaling | Changes capacity at specific dates/times. For demand you already know the shape of — business hours, overnight batch, a known launch window. |
| Predictive scaling | Forecasts capacity from historical usage and adds instances *ahead* of an expected spike, rather than reacting after it. Suits cyclical traffic with long instance warm-up times. |
Scheduled and predictive scaling combine with a dynamic policy rather than replacing it. Predictive handles the anticipated curve; target tracking catches whatever the forecast missed.
Auto Scaling pricing in plain English
The feature is free. What you pay for is the fleet it manages, which makes the group a lever on your EC2 bill rather than a cost of its own.
No charge for EC2 Auto Scaling itself. You pay for the EC2 instances the group launches, plus CloudWatch charges for the alarms backing dynamic scaling policies, plus any load balancer and data transfer costs — so an ASG's cost is entirely the cost of what it runs.
Keeping the bill down
- Scaling in is the whole point — a group whose minimum equals its maximum is a fixed fleet paying peak cost around the clock
- Mix Spot and On-Demand via a launch template's instance-distribution settings for fault-tolerant workloads; the group replaces reclaimed Spot capacity automatically
- Use target tracking rather than an over-provisioned fixed desired capacity — it's the difference between paying for peak and paying for load
- Predictive scaling avoids over-provisioning 'just in case' for workloads with a repeating daily/weekly shape
N/A — no per-group or per-region charge for the Auto Scaling feature. Rates as of 2026-08. Verify at the official pricing page before using for real cost estimates. The Auto Scaling feature is free; the cost that matters is the fleet it manages, which depends on instance type, purchase model, and how aggressively the group scales in.
There’s one way to get this badly wrong: setting minimum equal to maximum. That’s a fixed fleet wearing a scaling group’s clothes — peak cost around the clock, none of the elasticity.
How an Auto Scaling group connects to other services
The group’s edges are all control-plane: it launches instances, it registers them with a load balancer, it announces what it did. None of them carry your application’s data.
An Application Load Balancer distributes incoming traffic across the instances in this Auto Scaling group — the standard way to run a resilient, horizontally-scaled web/app tier
The Auto Scaling group launches and terminates the EC2 instances that make up the fleet, from a launch template
The group emits instance launch/terminate and lifecycle-hook events to EventBridge, so other systems can react to fleet changes without polling
A lifecycle hook notifies an SNS topic when an instance enters a wait state on launch or termination, so a subscriber can drain connections, copy logs off the instance, or complete setup
The ALB pairing is the one that matters most, and the mechanism is worth knowing exactly. You attach the ALB’s target group to the Auto Scaling group, and registration becomes automatic from then on — instances the group launches get registered, instances it terminates get deregistered. You never manage individual targets by hand.
The trap is zone alignment. The group’s subnets and the load balancer must cover the same Availability Zones. Launch into a zone the load balancer isn’t in and those instances sit there receiving nothing, healthy and useless.
Use launch templates, not the older launch configurations. Mixing Spot and On-Demand, and using multiple instance types, only exist on templates.
What an Auto Scaling group can’t connect to
The group boundary looks like it should own the application’s relationships. It doesn’t own any of them.
An Auto Scaling group manages instance capacity — it has no database client relationship. The application running on the EC2 instances inside the group is what connects to RDS, so that edge belongs on the EC2 node, not on the group boundary.
The group itself never reads or writes objects. Application code on the instances it launches does, using the instance profile attached via the launch template — draw that edge from EC2, not from the group.
Anti-patterns Design Beaver catches
Each of these leaves you with a group that looks right on a diagram and delivers roughly none of what a group is for.
An Auto Scaling group confined to a single Availability Zone
Why it breaksRemoves the main resilience benefit of using a group at all — if that zone fails, every instance in the fleet fails with it, and the group has nowhere else to launch replacements
Do this insteadGive the group subnets in at least two Availability Zones and keep at least one instance running in each; the group balances across them and rebalances automatically after a zone recovers
Running an Auto Scaling group with EC2 health checks only, behind a load balancer
Why it breaksEC2 status checks only detect a failed host. An instance whose application process has died still passes them, so it stays in service and keeps receiving traffic it can't serve
Do this insteadTurn on Elastic Load Balancing health checks for the group so the load balancer's view of application health drives instance replacement
Setting minimum capacity equal to maximum capacity
Why it breaksThe group can never scale in or out — it's a fixed fleet with extra configuration, paying peak cost continuously while providing none of the elasticity that justifies the group
Do this insteadSet a minimum that covers baseline load with zone redundancy, a maximum that covers peak, and a target tracking policy to move between them
Gotchas that bite in production
- A single-AZ group is mostly theatre. One subnet means one zone, and a zone failure takes the whole fleet with nowhere to launch replacements. Two subnets in two zones, minimum.
- EC2 health checks don’t catch a crashed application. They detect a failed host. Add ELB health checks so application health drives replacement.
- The grace period cuts both ways. Too short and the group kills instances mid-boot, then launches replacements that also don’t finish booting. Set it comfortably above real startup time.
- Lifecycle hooks fail quietly. A hook holds the instance until something tells it to continue or the timeout expires. A broken handler doesn’t error — it just takes the full timeout on every scale event, which reads as “scaling is mysteriously slow.”
- Cross-zone load balancing matters more than it sounds. With it off, each zone gets an equal share of traffic regardless of instance count, so during a failover the thinner zone gets hammered.
Further reading
- Official AWS documentation
- Attach a load balancer to your Auto Scaling group
- Health checks for your Auto Scaling group
- Availability Zone distribution
Frequently asked questions
When should you use an EC2 Auto Scaling group?
How much does an Auto Scaling group cost?
Why is my Auto Scaling group not replacing a broken instance?
Does an Auto Scaling group need more than one Availability Zone?
autoscaling-multiple-az). Give it at least two subnets in different zones.Can an Auto Scaling group connect to RDS or S3?
Validate your Auto Scaling Group architecture as you draw
Design Beaver checks your AWS design in real time — missing queues, invalid connections, and security anti-patterns, caught before you ship. It’s live in beta, free, and runs in your browser. Sign in with Google or GitHub to save your work.
Sign up for free! →Prefer email? Get new features in your inbox: