Home / AWS

AWSHow-toAdvanced

Optimization: tuning EC2 Auto Scaling - target tracking, predictive scaling, warm pools and mixed instances

Auto Scaling groups often run with a high fixed minimum because scale-out is too slow to trust. Make instances ready faster, use target tracking on the right metric, add predictive scaling for daily patterns, keep warm pools for slow-booting apps, and mix on-demand and spot across instance types.

Deepak Bhardwaj3 min read

Applies toAmazon EC2 Auto Scaling groups with launch templates, Application Load Balancer target groups, Spot Instances

The usual problem

MinSize is set to the daily peak "to be safe", because scaling out took 8 minutes the one time it was tried. The fix is to make scaling fast and trustworthy, then lower the floor.

1. Make instances ready faster

Step Fix
Long user data installing packages Bake a golden AMI (EC2 Image Builder); user data only for config
App start-up slow Profile it; warm caches lazily
Health check grace too long/short Set HealthCheckGracePeriod to real boot time; use ALB health checks
Default instance warm-up unset Set DefaultInstanceWarmup so new instances' metrics don't distort scaling

Measure: time from launch to InService and to healthy in the target group.

2. Target tracking on the right metric

aws autoscaling put-scaling-policy --auto-scaling-group-name web-asg --policy-name rps-target \
  --policy-type TargetTrackingScaling --target-tracking-configuration '{
    "PredefinedMetricSpecification": {"PredefinedMetricType": "ALBRequestCountPerTarget",
      "ResourceLabel": "app/web-alb/50dc6c495c0c9188/targetgroup/web-tg/943f017f100becff"},
    "TargetValue": 800.0
  }'
Workload Good metric
Web behind ALB ALBRequestCountPerTarget (find the per-instance rate where latency starts rising)
CPU-bound processing ASGAverageCPUUtilization ~50–60%
Queue workers Custom metric: backlog per instance (queue depth ÷ instances)

Avoid stacking several step policies that fight each other.

3. Predictive scaling for daily patterns

Predictive scaling forecasts load from history and launches capacity ahead of the curve. Start in forecast only mode, compare with actual load for a week, then switch to forecast and scale:

aws autoscaling put-scaling-policy --auto-scaling-group-name web-asg --policy-name predictive \
  --policy-type PredictiveScaling --predictive-scaling-configuration '{
    "MetricSpecifications": [{"TargetValue": 800,
      "PredefinedMetricPairSpecification": {"PredefinedMetricType": "ALBRequestCount",
        "ResourceLabel": "app/web-alb/50dc6c495c0c9188/targetgroup/web-tg/943f017f100becff"}}],
    "Mode": "ForecastOnly", "SchedulingBufferTime": 300 }'

Keep target tracking alongside it for unexpected spikes.

4. Warm pools for slow-booting apps

A warm pool keeps pre-initialised instances stopped (or hibernated), so scale-out resumes them instead of booting from scratch. You pay for stopped instances' EBS, not compute:

aws autoscaling put-warm-pool --auto-scaling-group-name web-asg --pool-state Stopped --min-size 2 \
  --instance-reuse-policy '{"ReuseOnScaleIn": true}'

Use lifecycle hooks so app initialisation completes before an instance goes into the warm pool.

5. Mixed instances and spot

"MixedInstancesPolicy": {
  "InstancesDistribution": {
    "OnDemandBaseCapacity": 2,
    "OnDemandPercentageAboveBaseCapacity": 30,
    "SpotAllocationStrategy": "price-capacity-optimized"
  },
  "LaunchTemplate": {
    "LaunchTemplateSpecification": {"LaunchTemplateName": "web-lt", "Version": "$Latest"},
    "Overrides": [{"InstanceRequirements": {"VCpuCount": {"Min": 2, "Max": 4}, "MemoryMiB": {"Min": 4096}}}]
  }
}
  • Attribute-based instance selection (InstanceRequirements) gives many spot pools automatically.
  • Enable Capacity Rebalancing so ASG replaces at-risk spot instances proactively.
  • Keep a small on-demand base for steady capacity.

6. Lower the floor

Once scale-out is fast and tested (load test from minimum to peak), reduce MinSize to what's needed for HA (e.g. 2 across AZs) plus a buffer for sudden spikes, and let scaling do the rest.

7. Scale-in safely

  • Connection draining: target group deregistration delay set to real request duration (the default 300 s is often too long).
  • Instance scale-in protection for instances running long jobs.
  • Termination policies that keep AZs balanced.

Tip

Run a load test that starts at the new minimum and ramps to peak faster than real traffic. If latency SLOs hold, the lower floor is safe; if not, you know exactly which step is slow.

Checklist

  • Launch-to-healthy time measured and reduced
  • Target tracking on a meaningful metric
  • Predictive scaling tested in forecast-only first
  • Warm pool for slow-booting apps
  • Mixed instances with spot diversification and rebalancing
  • MinSize lowered after a ramp test
  • Scale-in draining and protection tuned