Distribuée
AWS Advisory
← All insights

FinOps

Graviton: migrating your workloads to ARM without breaking anything

Evaluation method, real-world savings, and the pitfalls to avoid when migrating AWS workloads to Graviton (ARM) without operational risk.

· 5 min · #finops#graviton#arm#aws#ec2

Graviton isn’t an experimental option anymore. Four chip generations in, AWS is actively pushing customers toward ARM — and the numbers justify the migration effort. The question isn’t whether Graviton saves money (it does), it’s where it breaks in practice, and how to migrate without an all-nighter.

This article walks through the method we apply on Distribuée engagements: evaluate, quantify, migrate incrementally, no surprises in production.

Why Graviton, and why now

Graviton3 and Graviton4 run 10 to 19% cheaper per hour than equivalent Intel/AMD instances, at equal or better performance. Graviton4, available in EC2 instances since September 2024, delivers up to 30% more performance than Graviton3, for a 40% improved price-to-performance ratio. On documented real-world cases, the gap ranges from 20 to 47% less compute cost — Pinterest reported a 47% cost reduction on a key workload after migrating.

Concretely, on comparable on-demand instances (before any regional discount):

InstancevCPU / RAMPrice/h (base)
m7i.large (Intel)2 / 8 GB~$0.1008
m7g.large (Graviton3)2 / 8 GB~$0.0816

That’s roughly a 19% gap, before even counting the performance gain that often lets you downsize further. On Lambda, the gap is official and fixed: arm64 functions bill 20% less on duration than x86_64 ($0.0000133334/GB-s vs $0.0000166667/GB-s), on top of up to 34% better price-performance according to AWS. On RDS, Graviton2 brought up to 52% price-performance improvement on open-source engines versus equivalent Intel instances, and Graviton3 adds another 27% on top of Graviton2 for the same databases.

Those numbers sell themselves. They say nothing about the actual work: a CPU architecture switch touches everything that compiles native code.

What you actually gain, service by service

  • EC2: the immediate gain is the hourly rate (10-19%). The secondary gain, often larger, comes from right-sizing enabled by the better perf/vCPU ratio — many teams move an m7i.xlarge down to an m7g.large with no capacity loss.
  • Lambda: fixed, low-risk gain of 20% on duration. This is the service with the best effort/gain ratio for a Graviton migration, since there’s no instance to resize and no cluster to orchestrate.
  • RDS / Aurora: the highest cumulative gains (up to 52% vs x86 on Graviton2, +27% with Graviton3), but the switch requires an instance restart (or a failover for Multi-AZ) — plan for a maintenance window.
  • EKS / ECS: same compute-side gains as EC2, but the complexity shifts to container images and DaemonSets (see below).

Evaluation method before migrating

Never migrate blind. The sequence we follow:

  1. Inventory native dependencies. Any library with a C extension (Python numpy, pandas, compiled cryptography, native Node.js modules, already cross-compiled Go/Rust binaries) needs to be checked for arm64 wheel/package availability. Some niche libraries (e.g. Fiona for geospatial work) have historically lacked ARM builds — better to know before migrating than during an incident.
  2. AWS Compute Optimizer. It already flags instances eligible for a Graviton switch with the estimated savings:
aws compute-optimizer get-ec2-instance-recommendations \
  --query 'instanceRecommendations[].recommendationOptions[?instanceType && contains(instanceType, `g.`)].[instanceType,savingsOpportunity.savingsOpportunityPercentage]' \
  --output table
  1. Real application benchmarking, not just synthetic. A load test (k6, Locust) on a Graviton-switched staging environment gives you the real measurement — CPU theory doesn’t replace a P99 latency profile.
  2. Windows / AVX-512 check. Windows Server doesn’t run on Graviton (ARM-only architecture). Anything depending on specific x86 instructions (AVX-512, notably some scientific computing or optimized encryption workloads) stays on x86.

The pitfalls that break a Graviton migration

This is the part AWS marketing articles skip.

Multi-architecture Docker builds are pitfall #1. Unlike Go, Python and .NET don’t natively cross-compile. Building multi-arch images with QEMU under Buildx without dedicated caching can multiply build time by 5. The pattern that holds up over time: native ARM CI runners (GitHub Actions offers hosted arm64 runners, CodeBuild too), not continuous QEMU emulation.

Every sidecar matters, on Kubernetes. A single DaemonSet, monitoring agent, or security scanner that only exists as an x86 image simply blocks pod scheduling on Graviton nodes. Before creating an arm64 node group, audit every DaemonSet in the cluster, not just the application.

Existing Savings Plans and RIs don’t transfer automatically. A Compute Savings Plan covers any instance family, but an EC2 Reserved Instance is tied to a specific family and architecture. If you’re carrying x86 RIs, a Graviton migration leaves them underused until they expire — factor that into your ROI calculation.

Windows and AVX-512: no workaround. Don’t waste time looking for a porting solution — those workloads stay on x86 by design.

Migrating without breaking anything: the rollout pattern

The principle is the same as any risky infrastructure migration: canary, measure, generalize.

On EC2/ASG: use a Mixed Instances Policy to introduce a Graviton fraction into an existing Auto Scaling Group, alongside x86 instances, before the full switch.

resource "aws_autoscaling_group" "app" {
  # ...
  mixed_instances_policy {
    instances_distribution {
      on_demand_percentage_above_base_capacity = 100
    }
    launch_template {
      launch_template_specification {
        launch_template_id = aws_launch_template.app.id
      }
      override {
        instance_type = "m7i.large"
      }
      override {
        instance_type = "m7g.large"
      }
    }
  }
}

On EKS: create a separate arm64 node group with a dedicated taint, deploy a fraction of the deployment onto it via nodeSelector/tolerations, measure for 7 days, then progressively increase the replica share.

On Lambda: the simplest change of the lot — flip the architecture setting on the function config, republish, test in staging, then deploy to prod. No reason to skip this for any function without an unresolved native dependency.

In every case, the same rule as any FinOps optimization applies: one variable at a time, measure for at least 7 days before generalizing, documented rollback (revert to the previous launch template or node group version).

The stacked outcome

Cumulative Graviton savings by service: EC2, Lambda, RDS

On a $10,000/month compute bill split across EC2, Lambda and RDS, a well-executed Graviton switch — with no application behavior change — typically brings 15 to 25% immediate savings, before even the right-sizing enabled by the performance gain.

Conclusion

Graviton isn’t a bet: it’s a CPU architecture migration with a documented, measurable ROI. The risk isn’t in the principle, it’s in the execution — unchecked native dependencies, unprepared CI pipelines, forgotten DaemonSets. The method that works is the one that applies to any infrastructure migration: map before you move, migrate by canary, measure before you generalize.

If you’re running more than 20 EC2 instances or a sizeable EKS/ECS cluster still 100% x86, there’s very likely 15 to 25% of compute savings sitting unused in your account. Let’s start a Graviton assessment.

Found this useful? Share it.

Go further

A topic, a project, a question?

Distribuée supports demanding SMBs on AWS audit, FinOps and security.

Book 15 min