← All posts

The RAM per dollar curve: how C, M, R, and X families price memory

Published April 10, 2025

When engineering teams size EC2 instances, the default reflex is often to pick a general-purpose M-family instance. If a service needs 64 GiB of RAM, teams frequently spin up an m7g.4xlarge without calculating the underlying unit economics.

That default choice causes substantial overspending. AWS does not price compute and memory independently on EC2; it bundles them in rigid ratios. Compute-optimized instances (C-family) provide 2 GiB of RAM per vCPU, general-purpose instances (M-family) provide 4 GiB per vCPU, memory-optimized instances (R-family) provide 8 GiB per vCPU, and high-memory instances (X-family) provide 16 to 32 GiB per vCPU.

Because AWS prices these instances based on total hardware allocation, the effective rate you pay per gigabyte of RAM drops steeply as you move up the memory ratio curve. At the same time, the effective rate you pay per vCPU climbs.

Understanding this curve changes how you architect caches, search engines, databases, and in-memory datastores.


The memory pricing curve across C, M, R, and X families

To see how AWS prices memory, compare the 4-vCPU (xlarge) tier across the 7th and 8th generation Graviton families in us-east-1 (Linux on-demand):

Family Tier Instance Type vCPUs RAM (GiB) RAM : vCPU Ratio Hourly Price Effective Price / GiB-hr Effective Price / vCPU-hr
Compute-Optimized c7g.xlarge 4 8 2 : 1 $0.1450 $0.0181 $0.0363
General-Purpose m7g.xlarge 4 16 4 : 1 $0.1632 $0.0102 $0.0408
Memory-Optimized r7g.xlarge 4 32 8 : 1 $0.2142 $0.0067 $0.0536
High-Memory x8g.xlarge 4 64 16 : 1 $0.3908 $0.0061 $0.0977

The rate per gigabyte of memory plummets as the memory density increases:

However, the inverse happens to CPU pricing. If your application is pure CPU compute and needs minimal memory, running on an r7g.xlarge charges $0.0536 per vCPU-hr compared to $0.0363 on c7g.xlarge—a 47.7% premium for memory you are not using.

The pattern on x86 (Intel & AMD)

This pricing curve is not unique to Graviton. Intel Sapphire Rapids and AMD Genoa follow the identical economic model:

Instance Type Architecture vCPUs RAM (GiB) Hourly Price (us-east-1) Effective Price / GiB-hr Effective Price / vCPU-hr
c7i.xlarge Intel Xeon (Sapphire Rapids) 4 8 $0.1785 $0.0223 $0.0446
m7i.xlarge Intel Xeon (Sapphire Rapids) 4 16 $0.2016 $0.0126 $0.0504
r7i.xlarge Intel Xeon (Sapphire Rapids) 4 32 $0.2646 $0.0083 $0.0662
c7a.xlarge AMD EPYC (Genoa) 4 8 $0.2053 $0.0257 $0.0513
m7a.xlarge AMD EPYC (Genoa) 4 16 $0.2318 $0.0145 $0.0580
r7a.xlarge AMD EPYC (Genoa) 4 32 $0.2981 $0.0093 $0.0745

Across every processor architecture, memory bought on an R-series instance is ~35% cheaper per GiB than on an M-series instance, and ~64% cheaper per GiB than on a C-series instance.


The sizing mistake: buying RAM on M-series

The most common sizing mistake occurs when a memory-heavy application is deployed to an M-series instance because developers evaluate capacity in terms of RAM requirements alone.

Consider a concrete workload: an in-memory cache (Redis or Valkey), an OpenSearch shard, or a JVM service with a 48 GiB heap that requires 64 GiB of RAM to run safely with OS headroom.

If you fulfill this 64 GiB RAM requirement across different instance families, here is what happens to your bill:

Target RAM: 64 GiB Instance Type vCPUs RAM (GiB) On-Demand Hourly Price Monthly Cost (730 hrs) Savings vs. M-Series
General-Purpose m7g.4xlarge 16 64 $0.6528 $476.54 Baseline
Memory-Optimized r7g.2xlarge 8 64 $0.4284 $312.73 34.4% cheaper ($163.81/mo saved)
High-Memory x8g.xlarge 4 64 $0.3908 $285.28 40.1% cheaper ($191.26/mo saved)

Why does m7g.4xlarge cost $476.54 per month while x8g.xlarge costs $285.28 per month for the exact same 64 GiB of memory?

Because to obtain 64 GiB of RAM on an M-family instance, you are forced to buy 16 vCPUs.

If your Redis node or JVM heap only utilizes 2 to 4 cores of CPU capacity, the remaining 12 to 14 cores sit idle at 5% utilization. You are paying $191.26 per month in deadweight compute charges simply to acquire the memory address space.

Switching that node to an r7g.2xlarge cuts the monthly cost by $163.81 (34%). If the workload needs even fewer cores, moving to an x8g.xlarge cuts the bill by $191.26 (40%) per node while providing the exact same 64 GiB of memory.

In a cluster of 10 cache nodes, that single family change saves $22,951 per year.


Sizing formula: finding your workload ratio

Rw = Required Memory (GiB) / Required Peak vCPUs
  1. Measure Peak vCPU Demand: Profile your application under production peak load (e.g. p95/p99 traffic). Determine how many vCPUs are required to keep CPU utilization below target saturation (typically 60–70%).
  2. Measure Working Set Memory: Determine the actual resident set size (RSS), heap requirements, cache allocations, and OS buffer headroom.
  3. Calculate Rw and Match Family:
           Rw <= 2.0  -->  C-Family (Compute-Optimized, 2 GiB / vCPU)
  2.0  <   Rw <= 4.0  -->  M-Family (General-Purpose,   4 GiB / vCPU)
  4.0  <   Rw <= 8.0  -->  R-Family (Memory-Optimized,  8 GiB / vCPU)
           Rw >  8.0  -->  X-Family (High-Memory,      16-32 GiB / vCPU)

Sizing example: Vector search node

Suppose you are running an in-memory vector index (e.g. Qdrant or Milvus) that holds a 120 GiB index in memory:

Let’s evaluate the options on Graviton in us-east-1:

  1. M-family candidate: m7g.8xlarge (32 vCPUs, 128 GiB RAM) at $1.3056/hr ($953.09/mo). You get 32 cores when you only need 8 (75% CPU waste).
  2. R-family candidate: r7g.4xlarge (16 vCPUs, 128 GiB RAM) at $0.8568/hr ($625.46/mo). You get 16 cores when you only need 8 (50% CPU waste).
  3. X-family candidate: x8g.2xlarge (8 vCPUs, 128 GiB RAM) at $0.7816/hr ($570.57/mo). Matches both your 8 vCPU requirement and 128 GiB RAM requirement almost perfectly.

Choosing x8g.2xlarge instead of m7g.8xlarge reduces infrastructure spend by 40.1% ($382.52/month per node) without sacrificing a single query per second.


Memory bandwidth: DDR5 vs. DDR4 across generations

Capacity is only one dimension of memory performance. For in-memory databases, columnar query engines (ClickHouse, DuckDB), and high-throughput serialization pipelines, memory bandwidth is frequently the primary bottleneck before CPU execution units saturate.

AWS overhauled memory subsystems in the 7th and 8th generations by transitioning from DDR4 to DDR5:

Generation / Architecture         Memory Tech      Channels per Socket    Max Theoretical Bandwidth
---------------------------------------------------------------------------------------------------
Graviton2 (6th gen: m6g/r6g)       DDR4-3200        8 channels             ~204.8 GB/s
Graviton3 (7th gen: m7g/r7g)       DDR5-4800        8 channels             ~307.2 GB/s (+50%)
Graviton4 (8th gen: m8g/r8g)       DDR5-5600        12 channels            ~537.6 GB/s (+162%)
Intel Sapphire Rapids (c7i/m7i)    DDR5-4800        8 channels             ~307.2 GB/s (+50%)
AMD Genoa (c7a/m7a/r7a)            DDR5-4800        12 channels            ~460.8 GB/s (+125%)

Architectural takeaways for memory-bound engines:

  1. Graviton3 DDR5 Bandwidth Jump: Graviton3 (r7g) was the first cloud processor on AWS to support DDR5, delivering up to 50% higher memory bandwidth than Graviton2 (r6g). Workloads bottlenecked on memory access latency and streaming throughput saw immediate throughput gains at nearly identical hourly pricing.
  2. Graviton4 and AMD Genoa 12-Channel Designs: AMD Genoa (r7a) and Graviton4 (r8g) employ 12 memory channels per socket compared to 8 channels on Intel Sapphire Rapids (r7i). This provides roughly 50% higher aggregate memory bus width per socket, which translates directly to higher throughput in parallel analytical queries scanning large in-memory buffers.
  3. Bandwidth per Core: When evaluating R-family vs. X-family instances, note that X-family instances pack more RAM per vCPU. While this gives you the best price per GiB, the memory bus bandwidth is shared across fewer cores. If your workload is memory-bandwidth-bound rather than memory-capacity-bound, an R-series instance provides more memory channels per gigabyte than an X-series instance.

Summary & architecture checklist

When selecting instance types for stateful or memory-intensive services:

  1. Never buy an M-series instance just to satisfy a RAM target. If CPU utilization on your M-nodes is consistently below 30%, you are overpaying for unused compute capacity.
  2. Use R-series as the default for stateful services. For relational databases (PostgreSQL, MySQL), search clusters (OpenSearch), and standard cache layers, the 8:1 ratio of r7g or r8g delivers the lowest total cost of ownership.
  3. Use X-series when the memory-to-vCPU ratio exceeds 8:1. For massive in-memory datasets, Redis caches with high key volumes, and vector databases where query volume per gigabyte is moderate, x8g cuts another 10–15% off R-series pricing.
  4. Compare generational unit costs. Use the instance explorer and the comparison tool to check live pricing across regions and verify current on-demand and reserved rates for your target hardware.