A Complete Guide to Dynamic Scaling for AWS Auto Scaling Groups
Auto Scaling policies are rules that define how an Auto Scaling group should automatically adjust its capacity based on changing conditions. These policies enable your applications to scale in and out dynamically, ensuring optimal performance and cost efficiency by maintaining just the right number of EC2 instances needed to handle the current workload.
| Policy Type | Description | Best For |
|---|---|---|
| Target Tracking | Maintains a specific metric value | Predictable workloads |
| Step Scaling | Scales based on alarm thresholds | Variable workloads |
| Simple Scaling | Basic alarm-based scaling | Legacy applications |
| Scheduled Scaling | Scales at specific times | Predictable time patterns |
| Predictive Scaling | Scales based on forecasts | Recurring traffic patterns |
How Auto Scaling policies work:
Cooldown periods help ensure that your Auto Scaling group doesn't launch or terminate additional instances before the previous scaling activity takes effect.
# Set default cooldown aws autoscaling update-auto-scaling-group \ --auto-scaling-group-name my-asg \ --default-cooldown 180
# Set policy-specific cooldown aws autoscaling put-scaling-policy \ --auto-scaling-group-name my-asg \ --policy-name scale-out-policy \ --scaling-adjustment 1 \ --adjustment-type ChangeInCapacity \ --cooldown 60
Target tracking scaling policies automatically adjust capacity to maintain a specific metric value. This is the simplest and most recommended approach for most applications.
For example, you can set a target of 70% average CPU utilization. The policy will automatically add or remove instances to maintain this target.
Creating a target tracking policy via AWS CLI:
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name cpu-target-tracking-policy \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"
},
"TargetValue": 70.0,
"DisableScaleIn": false
}'
Common predefined metrics:
ASGAverageCPUUtilizationASGAverageNetworkInASGAverageNetworkOutALBRequestCountPerTargetUsing custom CloudWatch metrics:
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name custom-metric-tracking-policy \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"CustomizedMetricSpecification": {
"MetricName": "MyCustomMetric",
"Namespace": "MyNamespace",
"Dimensions": [
{
"Name": "MyDimension",
"Value": "MyValue"
}
],
"Statistic": "Average",
"Unit": "Count"
},
"TargetValue": 100.0
}'
Step scaling policies allow you to define different scaling adjustments based on the size of the alarm breach. This provides more granular control over scaling actions.
For example, you might add 1 instance when CPU is between 70-85%, but add 3 instances when CPU exceeds 85%.
Creating a step scaling policy requires two steps:
1. Create a CloudWatch alarm:
aws cloudwatch put-metric-alarm \ --alarm-name cpu-high-alarm \ --metric-name CPUUtilization \ --namespace AWS/EC2 \ --statistic Average \ --period 300 \ --evaluation-periods 2 \ --threshold 70 \ --comparison-operator GreaterThanThreshold \ --dimensions "Name=AutoScalingGroupName,Value=my-asg"
2. Create the step scaling policy:
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name cpu-step-scaling-policy \
--policy-type StepScaling \
--adjustment-type PercentChangeInCapacity \
--metric-aggregation-type Average \
--step-adjustments '[
{
"MetricIntervalLowerBound": 0,
"MetricIntervalUpperBound": 15,
"ScalingAdjustment": 10
},
{
"MetricIntervalLowerBound": 15,
"ScalingAdjustment": 30
}
]' \
--min-adjustment-magnitude 1
| Type | Description |
|---|---|
| ChangeInCapacity | Add or remove a specific number of instances |
| PercentChangeInCapacity | Add or remove a percentage of current capacity |
| ExactCapacity | Set the group to an exact number of instances |
Simple scaling policies adjust capacity based on a single CloudWatch alarm. Unlike step scaling, simple scaling doesn't provide granular adjustments based on the size of the alarm breach.
aws autoscaling put-scaling-policy \ --auto-scaling-group-name my-asg \ --policy-name simple-scaling-policy \ --scaling-adjustment 1 \ --adjustment-type ChangeInCapacity \ --cooldown 300 aws cloudwatch put-metric-alarm \ --alarm-name cpu-high-simple-alarm \ --metric-name CPUUtilization \ --namespace AWS/EC2 \ --statistic Average \ --period 300 \ --evaluation-periods 2 \ --threshold 70 \ --comparison-operator GreaterThanThreshold \ --dimensions "Name=AutoScalingGroupName,Value=my-asg" \ --alarm-actions "arn:aws:autoscaling:region:account-id:scalingPolicy:policy-id:autoScalingGroupName/my-asg:policyName/simple-scaling-policy"
Scheduled scaling allows you to set up scaling actions that occur at specific times, such as increasing capacity before a known traffic spike.
aws autoscaling put-scheduled-update-group-action \ --auto-scaling-group-name my-asg \ --scheduled-action-name increase-capacity-weekday-mornings \ --recurrence "0 8 * * 1-5" \ --min-size 5 \ --max-size 10 \ --desired-capacity 5
Common scheduling scenarios:
Predictive scaling uses machine learning to analyze historical workload patterns and forecast future capacity needs. It proactively scales your Auto Scaling group before anticipated load increases.
This is particularly useful for applications with regular traffic patterns, such as daily or weekly cycles.
Creating a predictive scaling policy:
aws autoscaling put-scaling-policy \
--policy-name predictive-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-type PredictiveScaling \
--predictive-scaling-configuration '{
"MetricSpecifications": [
{
"TargetValue": 70,
"PredefinedMetricPairSpecification": {
"PredefinedMetricType": "ASGCPUUtilization"
}
}
],
"Mode": "ForecastAndScale",
"SchedulingBufferTime": 300
}'
Predictive scaling modes:
You can apply multiple scaling policies to a single Auto Scaling group to handle different aspects of your application's scaling needs.
When multiple policies suggest different scaling actions, Auto Scaling chooses the one that provides the largest capacity.
Example of combining CPU and request count policies:
# CPU-based policy
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name cpu-policy \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"
},
"TargetValue": 70.0
}'
# Request count policy
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name request-count-policy \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ALBRequestCountPerTarget",
"ResourceLabel": "app/my-alb/778d41231b141a0f/targetgroup/my-targets/943f017f100becff"
},
"TargetValue": 1000.0
}'
You can use custom CloudWatch metrics to scale based on application-specific indicators that aren't available as predefined metrics.
# Publish custom metric
aws cloudwatch put-metric-data \
--namespace "MyApplication" \
--metric-name "ActiveConnections" \
--value 42 \
--dimensions "AutoScalingGroupName=my-asg"
# Create scaling policy with custom metric
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name custom-metric-policy \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"CustomizedMetricSpecification": {
"MetricName": "ActiveConnections",
"Namespace": "MyApplication",
"Statistic": "Average",
"Dimensions": [
{
"Name": "AutoScalingGroupName",
"Value": "my-asg"
}
]
},
"TargetValue": 100.0
}'
An e-commerce site that experiences varying traffic patterns throughout the day and during special sales events.
# Target tracking for normal traffic
aws autoscaling put-scaling-policy \
--auto-scaling-group-name ecommerce-asg \
--policy-name request-tracking \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ALBRequestCountPerTarget",
"ResourceLabel": "app/ecommerce-alb/targetgroup/main/123456"
},
"TargetValue": 1000.0
}'
# Scheduled scaling for sales events
aws autoscaling put-scheduled-update-group-action \
--auto-scaling-group-name ecommerce-asg \
--scheduled-action-name black-friday-scale-up \
--start-time "2024-11-29T00:00:00" \
--min-size 10 \
--max-size 30 \
--desired-capacity 20
A data processing system that scales based on SQS queue length.
# Custom metric based on queue length
aws autoscaling put-scaling-policy \
--auto-scaling-group-name data-processing-asg \
--policy-name queue-based-scaling \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"CustomizedMetricSpecification": {
"MetricName": "ApproximateNumberOfMessagesVisible",
"Namespace": "AWS/SQS",
"Dimensions": [{
"Name": "QueueName",
"Value": "data-processing-queue"
}],
"Statistic": "Average"
},
"TargetValue": 100.0
}'
Multiple services with different scaling requirements.
# API service with step scaling
aws autoscaling put-scaling-policy \
--auto-scaling-group-name api-service-asg \
--policy-name api-step-scaling \
--policy-type StepScaling \
--adjustment-type ChangeInCapacity \
--metric-aggregation-type Average \
--step-adjustments '[
{
"MetricIntervalLowerBound": 0,
"MetricIntervalUpperBound": 20,
"ScalingAdjustment": 1
},
{
"MetricIntervalLowerBound": 20,
"ScalingAdjustment": 2
}
]'