ARM vs Intel - A real-world comparison using EC2
Tags: ec2, aws, performance, cloud
Published: 2020-12-02 11:38:32

With the recent move from Apple to ARM-based CPUs, everyone seems to be in awe of the performance of the ARM-based Apple M1s. 

As a cloud engineer, I couldn't avoid asking if this performance translates to cloud computing too.

AWS has their line of ARM CPUs called [Graviton](https://aws.amazon.com/ec2/graviton/), available in their second generation as the `m6g` family in EC2. Those CPUs are on average 20% cheaper for the same amount of vCPUs and RAM, but how do they compare in terms of real-world performance, against traditional Intel CPUs? That's what we are here to find out.

# Setup

 | Intel | ARM
--- | --- | ---
Instance Count | 1 | 1
Instance Type | m5.large | m6g.large
CPU Tested | Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz | Custom built AWS Graviton2 Processor with 64-bit Arm Neoverse cores
CPU Count | 2 | 2
Clock (MHz) | 3397.426 | N/A
Region/AZ | ap-southeast-2c | ap-southeast-2c
Price (Sydney) | $0.120 per Hour | $0.096 per Hour

`cat /proc/cpuinfo` didn't show much information for the Graviton CPUs, I guess AWS wants to be secretive about it.

## Platform

The goal is to simulate a workload close to a real-world scenario, so we chose to use a Laravel API connecting to a MySQL database, which is a popular stack today.

The infrastructure used:

* AWS ECS running in EC2
* 2 Docker containers (ECS tasks) running the same App in one instance
* Containers limited to 1GB RAM (soft and hard limit), but no limit on CPU usage

## Application

* [RealWorld Example API, Laravel](https://github.com/gothinkster/laravel-realworld-example-app)
* PHP 7.1
* Apache/2.4.38 (Debian)

## Container

* Intel: `FROM php:7.1-apache`
* ARM: `FROM arm64v8/php:7.1-apache`

# Test Tool

```
ab -n 1000 -c 20 https://${HOST}/api/articles/test-post
^      ^      ^
⎮      |      ⎩ 20 concurrency
⎮      ⎩ 1000 requests
⎩ Apache Benchmark
```

# Results

## TL;DR

Graviton2 processors (m6g.large) are on average 25% faster than Intel on an m5.large instance. 

Given that m6g.large is 20% cheaper, we get a total of 40% gain in price/performance.

## Data (higher is better)

![single container, same database](https://dev-to-uploads.s3.amazonaws.com/i/mql0qitqnzlaugmcunk8.png)

Graviton2 is almost 29% faster when shooting requests to a single container and the database behind is exactly the same.

![2 containers, same database](https://dev-to-uploads.s3.amazonaws.com/i/6dmvbbgc2xz5j4dkp011.png)

When adding a second container to answer requests, interestingly Gravitons didn't see any improvement, while Intel did. The difference fell to 8% only

![2 containers, no database access](https://dev-to-uploads.s3.amazonaws.com/i/jw16q9490x0zhxx9lut3.png)

Testing with requests that do not require database access, the number of requests per second were higher for both, and Graviton kept a good margin against Intel of 26%.

![2 containers, database with the same instance type](https://dev-to-uploads.s3.amazonaws.com/i/v1ikjz1nafvtjy5x6e25.png)

As a bonus, we decided to match the same instance type in the database. That means that now the `m5.large` EC2 instance is connected to a `db.m5.large` RDS instance and the `m6g.large` to a `db.m6g.large` RDS instance.

Results were pretty similar to before, with a 22% advantage to Gravitons, meaning that for this specific test, the database was not a bottleneck.


# Final Thoughts

A simple change in your Dockerfile could mean a 40% cost reduction in your compute costs.

As M1 Macs become more popular, dev teams will be multi-platform, requiring environments (both local and cloud) to support different architectures. 

Docker also is working on better support for multi-platform images with [docker buildx](https://docs.docker.com/buildx/working-with-buildx/), making it more portable and easier to use the most cost-effective computing platform, independent of architecture.