The RAM per dollar curve: how C, M, R, and X families price memory
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:
- Moving from C7g ($0.0181/GiB-hr) to M7g ($0.0102/GiB-hr) cuts the effective cost per GiB by 43.6%.
- Moving from M7g ($0.0102/GiB-hr) to R7g ($0.0067/GiB-hr) cuts the effective cost per GiB by another 34.3%.
- Moving from C7g ($0.0181/GiB-hr) to X8g ($0.0061/GiB-hr) yields a 66.3% reduction in effective cost per GiB.
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
- 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%).
- Measure Working Set Memory: Determine the actual resident set size (RSS), heap requirements, cache allocations, and OS buffer headroom.
- Calculate
Rwand 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:
- Step 1 (Memory): Working set + OS page cache = 128 GiB RAM.
- Step 2 (Compute): Query throughput benchmark shows 500 QPS requires 8 active vCPUs.
- Step 3 (Ratio):
Rw = 128 GiB / 8 vCPUs = 16 GiB / vCPU
Let’s evaluate the options on Graviton in us-east-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). - 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). - 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:
- 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.
- 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.
- 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:
- 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.
- 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.
- 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.
- 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.