How to Compare EC2 Graviton2, Graviton3, and Graviton4?
Evaluating performance gains across AWS Graviton2, Graviton3, and Graviton4 instances in Amazon EC2 requires a structured benchmarking methodology that combines micro-architectural metrics, synthetic workloads, and production-grade application testing. As AWS evolves its custom Arm-based silicon from the Neoverse N1 in Graviton2 to the Neoverse V1 in Graviton3 and the Neoverse V2 in Graviton4, organizations must look beyond raw clock speeds and measure real-world throughput, tail latency, memory bandwidth, and price-performance efficiency to justify migration efforts.
Architectural Evolution Across Graviton Generations
Before executing benchmarks, it is essential to understand the hardware changes driving performance differences across each generation. Unlike traditional x86 processors that often utilize Simultaneous Multithreading (SMT), every vCPU on a Graviton instance is a physical core. This design eliminates thread contention between sibling hyperthreads and yields more predictable scaling.
| Feature | Graviton2 (6g) | Graviton3 (7g) | Graviton4 (8g) |
|---|---|---|---|
| Arm Architecture | Armv8.2-A (Neoverse N1) | Armv8.4-A (Neoverse V1) | Armv9.0-A (Neoverse V2) |
| L1 / L2 Cache per Core | 64 KB L1 / 1 MB L2 | 64 KB L1 / 1 MB L2 | 64 KB L1 / 2 MB L2 |
| Max vCPUs per Socket | 64 | 64 | 96 |
| Memory Technology | DDR4-3200 | DDR5-4800 | DDR5-5600 |
| SIMD / Vector Extensions | 2x 128-bit NEON | 2x 256-bit SVE | 4x 128-bit SVE2 |
| Floating Point / ML Support | FP16, INT8 dot-product | BF16, INT8 matrix multiply | BF16, FP16, SVE2-BFloat16 |
The jump from Graviton2 to Graviton3 introduced DDR5 memory, offering 50% more memory bandwidth, alongside Scalable Vector Extensions (SVE) and BFloat16 support for machine learning inference. Moving from Graviton3 to Graviton4 doubles the L2 cache per core to 2 MB, transitions to the Armv9 architecture with SVE2, increases memory speed to DDR5-5600, and expands maximum instance sizes up to 192 vCPUs in dual-socket configurations.
Step 1: Standardize the Software and Compiler Environment
Hardware improvements in Graviton3 and Graviton4 rely heavily on
modern Linux kernels, updated system libraries, and compiler flags that
exploit newer instruction sets. Testing an older binary compiled for
generic Arm64 (armv8-a) will fail to utilize features like
Large System Extensions (LSE), SVE, or SVE2, skewing your benchmark
results.
To ensure a fair evaluation across m6g (Graviton2),
m7g (Graviton3), and m8g (Graviton4)
instances:
- Operating System: Use Linux kernel 6.1 or later (such as Amazon Linux 2023 or Ubuntu 24.04 LTS) to ensure optimal scheduler awareness, page sizing, and hardware perf counter support.
- C/C++ and Rust Compilers: Use GCC 12+ or Clang/LLVM
15+ and compile with
-mcpu=nativeon each target instance, or target specific architectures explicitly (-mcpu=neoverse-n1,-mcpu=neoverse-v1,-mcpu=neoverse-v2). - Runtime Versions: Use OpenJDK 21+ for Java workloads, Go 1.21+ for Go services, Python 3.11+ for interpreted workloads, and Node.js 20+ for JavaScript applications. Newer runtimes contain intrinsic optimizations for Armv8.4 and Armv9 instructions.
Step 2: Measure Micro-Architectural Subsystem Gains
Before testing full applications, run targeted synthetic benchmarks to isolate how CPU compute, memory bandwidth, and cache hierarchies behave across the three generations.
Memory Bandwidth and Latency
Database engines, in-memory caches (like Redis or Valkey), and
analytics workloads are frequently bottlenecked by memory bandwidth
rather than CPU cycles. Because Graviton3 moved to DDR5 and Graviton4
doubled the L2 cache while increasing DDR5 clock rates, you should
quantify memory throughput using the STREAM benchmark or
sysbench:
sysbench memory --memory-block-size=1M --memory-total-size=100G --threads=$(nproc) runCompare the transferred megabytes per second across identically sized
instances (for example, r6g.2xlarge,
r7g.2xlarge, and r8g.2xlarge). Workloads with
large working sets will exhibit a steep reduction in LLC (Last Level
Cache) misses on Graviton4 due to the 2 MB per-core L2 cache.
Compute, Cryptography, and Compression
Graviton3 and Graviton4 feature enhanced cryptographic accelerators and wider vector units. You can evaluate raw cryptographic throughput using OpenSSL speed tests:
openssl speed -elapsed -evp aes-256-gcm
openssl speed -elapsed rsa2048For compression-heavy workloads (such as Kafka brokers, log ingestion
pipelines, or object storage gateways), benchmark zstd or
zlib-ng compression and decompression speeds across all
three instance families.
Step 3: Conduct Application-Level Load Testing
Synthetic benchmarks establish theoretical ceilings, but production decisions require testing with representative application traffic. Set up an isolated load generation environment where the load generator runs on a separate EC2 instance within the same Availability Zone and Placement Group to minimize network jitter.
Key Application Metrics to Capture
- Maximum Sustainable Throughput: Measure Requests Per Second (RPS) or Transactions Per Second (TPS) before error rates exceed acceptable thresholds.
- Tail Latency under Load: Compare \(P_{50}\), \(P_{95}\), and \(P_{99}\) latencies at fixed load intervals (for example, at 50% and 75% CPU utilization). Because Graviton cores do not share execution pipelines via hyperthreading, latency degradation follows a smoother curve up to high CPU utilization.
- Throughput at Target SLA: Determine the highest RPS an instance can sustain while keeping \(P_{99}\) latency below a strict service-level objective (e.g., \(P_{99} < 50\text{ ms}\)).
Calculate the relative performance gain \(G_{\text{perf}}\) between generations using the following formula:
\[G_{\text{perf}} = \left( \frac{\text{Throughput}_{\text{target}} - \text{Throughput}_{\text{baseline}}}{\text{Throughput}_{\text{baseline}}} \right) \times 100\%\]
Step 4: Profile Hardware Counters with Linux Perf
To understand why a workload runs faster on Graviton3 or
Graviton4, use the Linux perf tool to inspect hardware
performance monitoring units (PMUs). Ensure your test runs on enough
vCPUs (or dedicated metal instances) where hardware counters are
exposed, and capture Instructions Per Cycle (IPC), branch
mispredictions, and cache misses:
perf stat -e cycles,instructions,cache-references,cache-misses,L1-dcache-load-misses,L2D_CACHE_REFILL -p <PID> -- sleep 30When comparing output across generations, calculate the Instructions Per Cycle:
\[\text{IPC} = \frac{\text{Instructions}}{\text{Cycles}}\]
A higher IPC on Graviton4 compared to Graviton3 and Graviton2 indicates that the wider instruction decode front-end, improved branch predictor, and 2 MB L2 cache are keeping the execution units fed without stalling on main memory fetches.
Step 5: Evaluate Price-Performance Efficiency
Newer Graviton generations carry a slight on-demand hourly price premium over their predecessors, but their higher throughput per vCPU typically results in a lower total cost to serve a given workload.
To evaluate the true economic benefit, normalize your performance metrics against the hourly instance cost. Calculate the Cost Per Million Requests (\(C_{\text{req}}\)) for each instance family:
\[C_{\text{req}} = \frac{\text{Hourly Instance Price (USD)}}{\text{RPS}_{\text{SLA}} \times 3600} \times 10^6\]
Alternatively, compute the Price-Performance Ratio (\(R_{\text{pp}}\)) relative to Graviton2:
\[R_{\text{pp}} = \left( \frac{\text{Throughput}_{\text{New}}}{\text{Cost}_{\text{New}}} \right) \div \left( \frac{\text{Throughput}_{\text{Baseline}}}{\text{Cost}_{\text{Baseline}}} \right)\]
If \(R_{\text{pp}} > 1.0\),
migrating to the newer Graviton generation reduces your overall EC2
spend because you can either scale down the instance size (for example,
moving from an m6g.4xlarge to an m8g.2xlarge)
or reduce the total number of instances in your Auto Scaling group while
maintaining the same cluster capacity.