I tried the new EC2 Auto Scaling feature "reservations-then-balanced" for AZ distribution with capacity reservation priority
This page has been translated by machine translation. View original
Introduction
On June 30, 2026, a new AZ distribution strategy reservations-then-balanced was added to EC2 Auto Scaling.
With the traditional balanced-best-effort, AZ even distribution is prioritized, which could prevent reservations from being utilized when they are unevenly distributed across AZs. With reservations-then-balanced, it becomes possible to preferentially consume capacity reservations and distribute any instances beyond the reserved capacity across AZs.
| Item | balanced-best-effort | reservations-then-balanced |
|---|---|---|
| Priority during scale-out | Even AZ distribution | Capacity reservation consumption → AZ distribution |
| Deletion order during scale-in | AZ balance priority | Non-reserved instances deleted first (result of this verification) |
| Reservation utilization (3 reservations in AZ-a, 3-AZ configuration, this verification) | 1/3 at Desired=3 | 1/3 at Desired=3, confirmed up to 2/3 at Desired=5 |
Verification Environment
- Region: ap-northeast-1
- ODCR: t4g.nano × 3 instances, ap-northeast-1a, targeted
- Auto Scaling Group (ASG): 3-AZ configuration of ap-northeast-1a / 1c / 1d, Max=5
Verification
Creating the ODCR
A targeted ODCR of t4g.nano × 3 instances was created in ap-northeast-1a.
aws ec2 create-capacity-reservation \
--availability-zone ap-northeast-1a \
--instance-type t4g.nano \
--instance-platform "Linux/UNIX" \
--instance-count 3 \
--end-date-type unlimited \
--instance-match-criteria targeted
{
"CapacityReservationId": "cr-xxxxxxxxxxxxxxxxx",
"InstanceType": "t4g.nano",
"AvailabilityZone": "ap-northeast-1a",
"TotalInstanceCount": 3,
"AvailableInstanceCount": 3,
"State": "active",
"InstanceMatchCriteria": "targeted"
}
Creating the ASG (CloudFormation)
The ASG was created using the following CloudFormation template. The initial deployment uses balanced-best-effort (default), and is later switched to reservations-then-balanced.
CloudFormation template (click to expand)
AWSTemplateFormatVersion: "2010-09-09"
Description: >
ASG with reservations-then-balanced strategy.
t4g.nano instances with ODCR priority in AZ-a, then balanced across AZs.
Parameters:
CapacityReservationId:
Type: String
Description: "ODCR ID (e.g., cr-0123456789abcdef0) created by create-odcr.sh"
SubnetAZa:
Type: AWS::EC2::Subnet::Id
Description: "Subnet in ap-northeast-1a"
SubnetAZb:
Type: AWS::EC2::Subnet::Id
Description: "Subnet in ap-northeast-1c"
SubnetAZc:
Type: AWS::EC2::Subnet::Id
Description: "Subnet in ap-northeast-1d"
AmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-arm64
Description: "AMI ID (default: latest Amazon Linux 2023 ARM64)"
DesiredCapacity:
Type: Number
Default: 3
MinSize:
Type: Number
Default: 0
MaxSize:
Type: Number
Default: 5
Resources:
LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: !Sub "${AWS::StackName}-lt"
LaunchTemplateData:
ImageId: !Ref AmiId
InstanceType: t4g.nano
TagSpecifications:
- ResourceType: instance
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-instance"
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: !Sub "${AWS::StackName}-asg"
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
VPCZoneIdentifier:
- !Ref SubnetAZa
- !Ref SubnetAZb
- !Ref SubnetAZc
MinSize: !Ref MinSize
MaxSize: !Ref MaxSize
DesiredCapacity: !Ref DesiredCapacity
AvailabilityZoneDistribution:
CapacityDistributionStrategy: balanced-best-effort
CapacityReservationSpecification:
CapacityReservationPreference: capacity-reservations-first
CapacityReservationTarget:
CapacityReservationIds:
- !Ref CapacityReservationId
CapacityReservationSpecificationspecifies the ODCR as a target (capacity-reservations-first+ ODCR ID)AvailabilityZoneDistributionis initially created withbalanced-best-effortand later switched toreservations-then-balancedvia API
Before: Scale-out with balanced-best-effort
Results after setting Desired Capacity to 3.
| AZ | Instance ID | CR Preference | LifecycleState |
|---|---|---|---|
| ap-northeast-1a | i-0ea798b6xxxxxxxx | open | InService |
| ap-northeast-1c | i-07479a5fxxxxxxxx | open | InService |
| ap-northeast-1d | i-07391cc3xxxxxxxx | open | InService |
{
"Total": 3,
"Available": 2
}
As a result of even distribution across 3 AZs (a:1, c:1, d:1), only 1 instance from AZ-a's reservation was consumed, leaving 2 instances unused.
After: Scale-out with reservations-then-balanced
Switch to reservations-then-balanced using update-auto-scaling-group. In this verification, no immediate replacement of existing instances occurred due to this change.
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name reservations-balanced-demo-asg \
--availability-zone-distribution '{"CapacityDistributionStrategy":"reservations-then-balanced"}'
0 instances → 3 instances
During the initial scale-out, AZ balance is also considered simultaneously, so in this verification, reservation consumption remained at 1 instance (1/3), the same as with balanced-best-effort. The difference became clear from the next scale-out onward.
1 instance in AZ-a was placed in the reservation (capacity-reservations-only), and the remaining 2 were distributed across c and d.
| AZ | Instance ID | CR Preference | Capacity Reservation |
|---|---|---|---|
| ap-northeast-1a | i-08fcce94xxxxxxxx | capacity-reservations-only | cr-xxxxxxxxxxxxxxxxx |
| ap-northeast-1c | i-0ef98d3axxxxxxxx | open | — |
| ap-northeast-1d | i-015bca4cxxxxxxxx | open | — |
ODCR remaining: 2/3 (Available: 2)
3 instances → 5 instances
Of the 2 additional instances, 1 was placed in AZ-a consuming a reservation, and the other was placed in AZ-c. ODCR consumption increased to 2/3.
| AZ | Instance ID | CR Preference | Capacity Reservation |
|---|---|---|---|
| ap-northeast-1a | i-08fcce94xxxxxxxx | capacity-reservations-only | cr-xxxxxxxxxxxxxxxxx |
| ap-northeast-1a | i-085d201exxxxxxxx | capacity-reservations-only | cr-xxxxxxxxxxxxxxxxx |
| ap-northeast-1c | i-0ef98d3axxxxxxxx | open | — |
| ap-northeast-1c | i-00cb22cfxxxxxxxx | open | — |
| ap-northeast-1d | i-015bca4cxxxxxxxx | open | — |
ODCR remaining: 1/3 (Available: 1)
Scale-in: Confirming that reserved instances remain
Desired Capacity was reduced from 5 to 3. Non-reserved instances were deleted first, and instances using reservations remained.
Deleted instances:
| Instance ID | AZ | CR Preference |
|---|---|---|
| i-015bca4cxxxxxxxx | ap-northeast-1d | open |
| i-00cb22cfxxxxxxxx | ap-northeast-1c | open |
Remaining instances:
| AZ | Instance ID | CR Preference | Capacity Reservation |
|---|---|---|---|
| ap-northeast-1a | i-08fcce94xxxxxxxx | capacity-reservations-only | cr-xxxxxxxxxxxxxxxxx |
| ap-northeast-1a | i-085d201exxxxxxxx | capacity-reservations-only | cr-xxxxxxxxxxxxxxxxx |
| ap-northeast-1c | i-0ef98d3axxxxxxxx | open | — |
As a result, the AZ distribution is skewed to a:2, c:1, but the reservation utilization rate is maintained (ODCR remaining: 1/3).
Summary
reservations-then-balanced is an effective AZ distribution strategy for configurations with capacity reservations that are unevenly distributed across AZs.
In this verification, with 3 ODCR instances concentrated in a single AZ, balanced-best-effort consumed only 1 reserved instance at Desired=3. On the other hand, with reservations-then-balanced, reservation consumption progressed to 2/3 when scaling out from Desired=3 to 5, and it was confirmed that instances using reservations remained during scale-in.
When reservations can be evenly distributed across AZs, the traditional balanced-best-effort tends to align well with both even AZ distribution and reservation consumption. When reservations are concentrated in a specific AZ, reservations-then-balanced becomes a strong candidate. In either case, it is recommended to verify the actual placement results to confirm that reservations are being consumed as intended.
Reference Links
