5 min
read
Introduction
In the ever-evolving world of cloud computing, cost optimization and performance improvement are top priorities. ARM architecture, with its AWS Graviton processors, offers a powerful and cost-effective alternative to traditional x86 architectures.
This article highlights our expertise and experience in migrating workloads to ARM instances, emphasizing the benefits, challenges, and best practices involved.
Why Choose ARM Architecture (Graviton)?
AWS Graviton processors, based on ARM architecture, provide several significant advantages:
- Cost reduction: Graviton instances are often more economical than their x86 equivalents, enabling substantial savings on infrastructure expenses.
- Improved performance: For many workloads, Graviton processors can deliver better performance per watt, resulting in faster and more efficient execution.
- Energy efficiency: ARM processors are known for their low power consumption, which reduces both carbon footprint and operating costs.
- Versatility: Graviton processors are suitable for a wide range of workloads, from web servers and databases to data analytics and high-performance computing.
Cost Comparison: Before and After ARM Migration
Migrating to ARM architecture, especially with Graviton instances, offers substantial financial benefits. Below is a cost comparison for common use cases:
💰x86 vs ARM (Paris region)

Note: The hourly costs are indicative and may vary depending on the AWS region, pricing options (Reserved, Spot), and specific workloads.
For AWS Lambda functions, running on ARM architecture (Graviton2) typically results in a 20% cost reduction while delivering improved performance compared to x86 architecture. This optimization is especially beneficial for large-scale serverless applications, where savings can quickly accumulate.
How to Migrate Your AWS Workloads to ARM
Our teams have developed strong expertise in migrating containerized workloads to ARM instances on AWS. Our approach includes:
- Assessment and planning: We perform an in-depth analysis of existing applications to identify compatibility, dependencies, and necessary optimizations.
- Software compatibility: We work with development teams to ensure that source code, libraries, and tools are compatible with ARM architecture, or to identify the changes required.
- Performance and integration testing: We conduct rigorous testing to ensure that expected performance levels are met and that integration with AWS services is seamless.
Continuous optimization: Even after migration, we continue to monitor and optimize workloads to fully leverage the capabilities of ARM architecture.
Experience with AWS Services
You can run containers on AWS through three main services:
- AWS Lambda
- Amazon Elastic Container Service (ECS), with two execution modes:
- on Fargate (serverless)
- on EC2
- Amazon Elastic Kubernetes Service (EKS)
Before diving into the specific migration aspects of each of these services, let’s look at the common requirement across all of them: the need to build container images for the new target architecture.
Building Images (Build)
Native builds (Build ARM on ARM host)
The goal is to build the image directly on an ARM64 architecture: a Graviton instance, an AWS CodeBuild Arm64 instance, or a Mac with an Apple Silicon chip (M1 or later).

Emulated builds (Build ARM on x86 host)
The goal is to build an Arm64 image from an x86 machine (emulation):
- Use BuildKit via docker buildx
- QEMU emulates the Arm64 processor

Additional notes on builds
Native builds are often faster and more reliable since there is no emulation involved — this is the best option if you have access to an ARM64 environment (Graviton EC2, Mac M1, CodeBuild Arm64).
Emulated builds (via buildx + QEMU) are very convenient for generating multi-platform images on x86 machines, but they can be much slower and more complex.
Multi-Architecture Manifests
A multi-architecture manifest allows you to group multiple Docker images built for different architectures (such as x86_64, ARM64, etc.) under a single unified tag. When you run a docker pull, the engine automatically detects your architecture and fetches the corresponding version.

- Building specific images: Separate Docker images, each specific to a given architecture (e.g., amd64, arm64), are generated and then pushed to a container image registry (e.g., Docker Hub, Amazon ECR).
- Creating the manifest file: A manifest file (or manifest list), which is an index file, is created. It references the architecture-specific images, mapping each image to its corresponding architecture. This manifest is then pushed to the registry with a unified tag (e.g., my-app:latest).
- Running containers: When executed (e.g., docker run my-app:latest), the Docker client queries the Container Registry for the manifest file. It identifies its own architecture, downloads the appropriate image, and instantiates the container seamlessly.
These multi-architecture manifests are very useful because:
- They simplify the CI/CD workflow: one tag for all architectures, no need to manage separate variants.
- High flexibility: a single image can be used on EC2 Graviton (ARM) as well as on x86 servers without changing the configuration.
Building Multi-Architecture Manifests with Emulation
The simplest one-step method with buildx:

Building Multi-Architecture Manifests Natively




Recommended CI/CD Workflow

This diagram illustrates a continuous integration and deployment (CI/CD) pipeline optimized for building multi-architecture applications (Arm and x86). Starting from a single code repository, the process splits into two parallel flows, each using a native runner to compile, test, and publish a container image specific to its architecture. Once these two images are validated, a consolidation step merges them into a single manifest. This manifest then enables deployment environments to automatically download the appropriate image version (Arm or x86) for their architecture, ensuring a simple and transparent final deployment process across both platforms.
AWS Lambda: Migration to ARM
A particularity of Lambda: as of now, the service does not support multi-architecture images.
To run a Lambda function on ARM64 architecture (via AWS Graviton2 processors), you only need to modify one parameter in its configuration. In your function’s Runtime settings, you must:
- Change the Architecture field from x86_64 to arm64.
- Provide a Docker image corresponding to the ARM64 architecture (no manifest!).

ECS Fargate: Migration to ARM
To migrate a Fargate workload to ARM, you must explicitly specify the architecture in the task definition configuration. This is done by adding or modifying the runtimePlatform field in the task definition JSON, assigning it the value ARM64 to indicate that the task should run on an ARM architecture. This change ensures that Fargate allocates ARM-based resources for your application.

ECS (EC2 mode): Migration to ARM
Migrating an ECS workload in EC2 mode to ARM architecture requires two key steps.
Create an ARM Capacity Provider
Associate a new ECS Capacity Provider with an EC2 Auto Scaling Group (ASG). This ASG must be configured to launch ARM instances (e.g., t4g, m6g, c6g) with an ECS-optimized ARM64 AMI. Integrate this Capacity Provider into your ECS cluster strategy to enable a progressive migration or mixed workloads.
Constraining Tasks to ARM
Configure your services or tasks to specifically use this ARM Capacity Provider. For added security, include a placement constraint in the task definition to enforce execution on an ARM64 architecture.
Here is an example of a placement constraint to add in the task definition:

In summary, Capacity Providers optimize the migration by automating the management and adjustment of Graviton instances. You simply need to specify the required capacity type for your tasks (ARM or x86), and ECS, through the Capacity Provider, ensures that the appropriate infrastructure is provisioned.
EKS (Kubernetes): Migration to ARM
To migrate an Amazon EKS (Elastic Kubernetes Service) cluster to ARM architecture, the approach is similar to ECS in EC2 mode. It involves provisioning ARM-based compute nodes (worker nodes) and ensuring that your applications (pods) run on these new nodes.
Adding ARM Compute Nodes
To integrate AWS Graviton (ARM64) instances into your EKS cluster, the recommended approach is to use Managed Node Groups.
When creating your node group, the key steps are as follows:
- Select the ARM instance type: Choose Graviton instance families such as m6g, c6g, or r6g.
- Use an ARM-optimized AMI: EKS provides official AMIs specifically optimized for Kubernetes and compatible with ARM64 architecture. It is entirely possible and even recommended to operate with a heterogeneous cluster, combining x86_64 and arm64 node groups. This setup supports a gradual and controlled migration.
Karpenter
An effective alternative for autoscaling is Karpenter, an open-source tool recommended by AWS for EKS. It enables dynamic provisioning of nodes (Graviton/x86), optimizes costs with Spot Instances, and simplifies configuration for flexible and cost-efficient resource management.
Scheduling Pods on ARM Nodes
Once ARM nodes are available, you need to configure Kubernetes to deploy your ARM-compatible applications on these nodes. To do this, use Kubernetes’ built-in scheduling mechanisms.
Kubernetes automatically assigns labels to nodes, such as kubernetes.io/arch=arm64. This label can be used to ensure your pods run exclusively on the appropriate nodes.
The most common method is to specify a nodeSelector or node affinity (nodeAffinity) in your deployment or pod definition.
Here’s a simple example using nodeSelector:

Customer Use Case: Jump – ARM Migration and Integrated Version Upgrade
Customer Context
Jump is a French platform that enables freelancers to maintain their independence while benefiting from employee rights (payslip, insurance, paid leave, etc.) through a wage portage model. Jump aimed to optimize its infrastructure costs and improve the performance of its containerized applications. Their existing x86-based architecture was stable but no longer allowed for the desired efficiency gains. In addition, there was a need to upgrade several Kubernetes clusters in parallel with the ARM migration.
Project Objectives
- Migrate containerized workloads to AWS Graviton (ARM64) instances.
- Significantly reduce infrastructure costs.
- Improve overall application performance.
- Integrate the ARM migration with an upgrade of several major software components.
- Implement a robust, modern CI/CD pipeline.
- Adopt Karpenter for EKS node autoscaling management.
Challenges Encountered and Solutions Provided
The project with Jump presented complex challenges due to the combined nature of the ARM migration and the version upgrade of the application ecosystem. The most critical points were:
- Managing version and architecture complexity: The coexistence of different software versions and the need to support both x86 and ARM made the planning and testing phases particularly demanding. We implemented exhaustive testing strategies and dedicated pre-production environments to validate each step of the migration and version upgrade.
- Implementing a multi-architecture CI/CD pipeline: The biggest challenge was modernizing and adapting Jump’s CI/CD pipeline so that it could build and deploy container images for both x86 and ARM64 architectures seamlessly. We implemented multi-architecture builds using Docker buildx and Docker manifests, enabling a single image tag to serve all architectures. This required a redesign of the existing build and deployment pipelines.
- Migration and adoption of Karpenter on EKS: Integrating Karpenter was another key point. Initially, Jump used more traditional managed node groups. Transitioning to Karpenter enabled more dynamic and cost-effective management of EKS nodes, fully leveraging Spot Instances and the fast autoscaling capabilities of Graviton instances. We supported Jump’s teams in configuring Karpenter provisioners, defining rules for architecture and instance type selection (including Graviton) to optimize resource utilization.
- Compatibility: The lack of availability of some components or tools often outdated and unmaintained provided an opportunity to streamline resources and clean up Kubernetes clusters.
Results and Benefits
The successful migration and the implementation of new practices enabled Jump to:
- Achieve substantial savings on cloud infrastructure costs through the widespread adoption of Graviton instances.
- Benefit from a significant performance boost for their critical applications.
- Have a modernized and flexible CI/CD pipeline, capable of managing deployments across different architectures with a single source of truth.
- Optimize Kubernetes resource utilization via Karpenter, making their infrastructure more elastic and resilient.
- Ensure a smooth and controlled transition (with no service interruptions) despite the complexity of a migration combined with a major version upgrade.
This use case illustrates our ability to manage complex migration projects, integrating not only architectural changes but also deep technological evolutions and the optimization of DevOps practices.
Limitations and Challenges of Migrating to ARM
While migrating to ARM architecture offers substantial benefits, it can also present challenges and limitations that are important to consider:
- Significant migration effort for certain projects: For complex or monolithic applications, the transition to ARM can require considerable development and testing efforts. Architecture-specific x86 software dependencies, native compilations, or incompatible tools may require deep adjustments.
- Software compatibility: Although the ARM ecosystem is improving rapidly, some less common software or libraries may not yet be fully optimized or available for this architecture. This may require exploring alternative solutions or implementing adaptations.
- Interpreted platforms: For projects based on languages such as PHP, Python, NodeJS, or Java, the abstraction layer provided by virtual machines or interpreters generally makes the application agnostic to the underlying architecture. However, native dependencies (extensions, C/C++ libraries) used by these applications may require recompilation or ARM-specific versions.
- CI/CD tools and integrations: CI/CD toolchains may need updates to support multi-architecture builds or ARM test environments, adding initial complexity to the setup.
It is crucial to carefully evaluate these points during migration planning to ensure that the expected benefits justify the investment. A gradual and well-structured approach is essential to minimize disruption and maximize the success of the transition.
Conclusion
Migrating to ARM architecture, particularly with AWS Graviton processors, offers a significant opportunity to optimize cloud infrastructures. Our expertise enables us to support our clients in this transition, managing the challenges and fully leveraging the advantages of this technology.
We guide our clients in modernizing their applications, containerizing them, and implementing CI/CD pipelines. Most of these evolutions should be managed through Infrastructure as Code (IaC) and GitOps best practices. We are ready to support you in adopting these practices if they are not yet in place within your organization.
Ready to transform your operations? Contact us for a smooth and efficient ARM migration.