Moving EC2 to Graviton: when arm64 saves money
When moving an EC2 instance to its Graviton (arm64) twin saves money, what has to change first, and how to roll it out.
Contents
In short
- Graviton instances cost less per hour than their x86 twins of the same size.
- Your software has to run on arm64: rebuild the image and test it first.
- Move one service at a time, behind the same load balancer, and keep the x86 launch template for rollback.
Graviton instances run on AWS’s own arm64 processors. For most EC2 families there is a Graviton instance with the same vCPU count and memory as the x86 one you run today, and it costs less per hour. The catch is the architecture: an x86 image won’t boot on arm64, so the move is a rebuild and a rollout, not a resize.
This guide shows how to find the instances worth moving, check that your software runs on arm64, roll the change out behind the same load balancer, and keep a way back.
What you save
AWS says Graviton instances cost up to 20% less than comparable x86-based instances and deliver up to 40% better price-performance. Here is what that looks like for one size, on-demand Linux in us-east-1, as of October 2026 (EC2 on-demand pricing):
| Instance | Architecture | vCPU / memory | Per hour | Per month (730 h) |
|---|---|---|---|---|
| m5.large | x86_64 | 2 / 8 GiB | $0.096 | $70.08 |
| m6i.large | x86_64 | 2 / 8 GiB | $0.096 | $70.08 |
| m7i.large | x86_64 | 2 / 8 GiB | $0.1008 | $73.58 |
| m6g.large | arm64 | 2 / 8 GiB | $0.077 | $56.21 |
| m7g.large | arm64 | 2 / 8 GiB | $0.0816 | $59.57 |
| m8g.large | arm64 | 2 / 8 GiB | $0.08976 | $65.52 |
Moving an m5.large to an m6g.large saves $13.87 a month, about 20%. On one instance that rarely justifies the work. On an Auto Scaling group of 40 instances it is $554.80 a month, every month. Newer Graviton generations cost a little more per hour than m6g but do more work per hour, so pick the generation after you test, not from the price column alone.
Find the candidates
List every running x86 instance, region by region:
for r in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
echo "== $r"
aws ec2 describe-instances --region "$r" \
--filters Name=instance-state-name,Values=running Name=architecture,Values=x86_64 \
--query 'Reservations[].Instances[].[InstanceId,InstanceType,Tags[?Key==`Name`]|[0].Value]' \
--output table
done
The best candidates are fleets: Auto Scaling groups, ECS container hosts and EKS node groups running stateless services. One rebuilt image moves dozens of instances. Leave these for later:
- Idle instances. Stop them instead. See how to find and stop idle EC2 instances.
- Oversized instances. Rightsize first, then move the smaller size. See rightsizing EC2 and RDS.
- Windows instances. Graviton runs Linux.
Check that the twin exists in your region and matches the size:
aws ec2 describe-instance-types --region us-east-1 \
--instance-types m5.large m6g.large m7g.large \
--query 'InstanceTypes[].[InstanceType, ProcessorInfo.SupportedArchitectures[0],
VCpuInfo.DefaultVCpus, MemoryInfo.SizeInMiB]' \
--output table
Check that your software runs on arm64
This is the step that decides whether the saving is real.
- Runtimes. Interpreted and JIT languages (Python, Node.js, Java, Ruby, PHP) and Go usually run unchanged. Native extensions and compiled dependencies need arm64 builds.
- Containers. Build multi-architecture images so the same tag runs on both:
docker buildx build --platform linux/amd64,linux/arm64 \
-t 123456789012.dkr.ecr.us-east-1.amazonaws.com/web:1.4.0 --push .
- Agents. Monitoring, logging and security agents on the host need arm64 builds too.
- Vendor software. A licensed binary with no arm64 build ends the move for that service.
Start from an arm64 base image. Amazon Linux publishes its latest one in a public SSM parameter:
aws ssm get-parameter --region us-east-1 \
--name /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-arm64 \
--query Parameter.Value --output text
Bake your image from it, then confirm the result:
aws ec2 describe-images --image-ids ami-0123456789abcdef0 \
--query 'Images[0].Architecture' --output text
It should print arm64.
Roll it out behind the same load balancer
You can’t change an x86 instance’s type to a Graviton type in place, because its image is x86. You launch new instances from the arm64 image and retire the old ones. For an Auto Scaling group:
- Add a launch template version with the arm64 image and the Graviton type. Keep the current version untouched.
V=$(aws ec2 create-launch-template-version \
--launch-template-id lt-0abc123def4567890 --source-version 3 \
--version-description "arm64 on m6g.large" \
--launch-template-data '{"ImageId":"ami-0123456789abcdef0","InstanceType":"m6g.large"}' \
--query LaunchTemplateVersion.VersionNumber --output text)
echo "New version: $V"
$V holds the new version’s number, which the next two steps use.
- Run one canary from the new version and register it with the group’s target group. Compare its error rate and latency with the x86 instances for a day.
aws ec2 run-instances --launch-template LaunchTemplateId=lt-0abc123def4567890,Version=$V
aws elbv2 register-targets --target-group-arn <target-group-arn> \
--targets Id=<canary-instance-id>
- Point the group at the new version and replace its instances gradually:
aws autoscaling update-auto-scaling-group --auto-scaling-group-name web-asg \
--launch-template LaunchTemplateId=lt-0abc123def4567890,Version=$V
aws autoscaling start-instance-refresh --auto-scaling-group-name web-asg \
--preferences '{"MinHealthyPercentage":90,"InstanceWarmup":300}'
aws autoscaling describe-instance-refreshes --auto-scaling-group-name web-asg \
--query 'InstanceRefreshes[0].[Status,PercentageComplete]' --output text
To roll back, point the group at version 3 and start another refresh. Terminate the canary when you’re done.
For a single instance, launch its replacement from the arm64 image with the same settings, move its Elastic IP or DNS record, stop the old instance and keep it stopped for a week before you terminate it.
Watch your commitments
Compute Savings Plans apply to any instance family, so they keep covering you after the move. EC2 Instance Savings Plans cover one instance family in one Region: a plan bought for m5 won’t cover m6g. If you hold one, time the move for when it ends, or size the next commitment as a Compute Savings Plan. See how to size a Compute Savings Plan.
When to leave it
The price difference is certain. Whether your software runs on arm64 isn’t, which is why Omni FinOps marks this lead as low confidence. Skip it when a dependency has no arm64 build, when the instance is a one-off whose saving won’t repay the testing, or when the team is mid-migration on something else. Revisit it with the next base image rebuild, when the cost of trying is lowest.
Mateo Vargas writes Omni FinOps’ cost guides, from the same rules the product runs on every refresh. Prices are list prices in us-east-1 or us-central1 as of October 11, 2026; check your region’s pricing page.