TL;DR: An Auto Scaling Group adds instances when demand is high and removes them when it's quiet — you set min/max/desired and scaling policies, AWS executes. The savings are structural: over-provisioning ("10 instances just in case") wastes money, under-provisioning drops traffic, and an ASG lets you run a low baseline and burst only when needed. Layer a mixed On-Demand/Spot instances policy on top and the same elasticity gets dramatically cheaper.
The numbers
- Three knobs: min (floor, even at 3 AM), max (ceiling), desired (current target, moved automatically by policies).
- Policy types: target tracking ("keep CPU ~50%", easiest and most common), step (graduated thresholds), scheduled (known daily patterns).
- Core saving: 10 instances at peak but only 3 needed 80% of the time → without ASG 240 instance-hours/day; with ASG (3 × 19.2h + 10 × 4.8h) = 105.6 → ~56% less compute.
- Cooldown default 300s prevents runaway scaling while new instances boot; ELB health checks catch app-level failures EC2 checks miss.
- Field examples: an e-commerce site with daily peaks cut $800→$350/mo (>50%) with scheduled + target-tracking; a bursty microservices API ran 60% cheaper via request-count target tracking + a mixed On-Demand-base/Spot policy.
Do this
- Default to target-tracking policies (CPU, request-count-per-instance, or a custom CloudWatch metric like queue depth) — they handle most cases with minimal tuning.
- Add scheduled scaling for predictable patterns (scale up weekday 8 AM, down at 6 PM) and let target-tracking absorb the variance.
- Enable ELB health checks for web apps — an instance can be "running" per EC2 yet failing to serve traffic; ELB checks catch that and replace it.
- Add a mixed-instances policy for interruption-tolerant tiers — an On-Demand base for reliability plus Spot above it, with capacity-optimized allocation and diversified instance types; ASG auto-replaces reclaimed Spot.
- Version launch templates and spread across AZs — versioned templates give clean rollbacks; multi-AZ gives HA for free.
Gotchas
- Cooldowns matter — without them, an ASG can launch instance after instance while the first ones are still booting and CPU is still high; the 300s default gives metrics time to settle.
- EC2 health checks miss application failures — use ELB checks behind a load balancer.
- A too-low max caps you during real spikes; a too-high min wastes money at idle — size both to observed patterns, not fear.
- Lifecycle hooks are the escape hatch for graceful connection draining or config pulls on launch/terminate.
Skip this if
- The workload is genuinely flat 24/7 — an ASG still gives HA (auto-replacement), but the elasticity savings are small; commit the steady baseline with Reserved Instances or Savings Plans instead.
- You want guaranteed capacity with no interruption risk — skip the Spot mix and run On-Demand. For interruption-tolerant burst capacity, pair with Spot Instances; for dev/test that's idle off-hours, EC2 Instance Scheduling is the simpler lever; for advanced multi-pool provisioning, EC2 Fleet.