EC2 Instance Families Compared: Choosing Between t, m, c, and r

6 min read

EC2 offers more than 800 instance types, but the choice narrows to two steps: which family, and which size. This post covers the first step, the family decision. The conclusion up front: the default is the latest-generation m family, and you move to c or r only when measurements show a clear skew toward CPU or memory. The t family looks cheap but is cheap only under specific conditions. The general skill of reading cloud instance specs is covered in Hardware Basics #9; here we focus on the AWS-side decision. Prices are for us-east-1 at on-demand rates.

Reading the name: family, generation, attributes #

m8g.large breaks into three parts: the first letter m is the family (the workload profile), the digit 8 is the generation, and the trailing letters are attributes. A handful of attribute letters covers most of what you will see.

  • g: AWS Graviton (ARM) processors. m8g, c8g, and r8g are the current generation.
  • i: Intel. m8i and c8i (Xeon 6) are the newest; m7i is the widely deployed generation.
  • a: AMD EPYC, typically priced about 10% below same-generation Intel.
  • d: local NVMe SSD attached — ephemeral disks whose data disappears when the instance stops.
  • n: enhanced network bandwidth.
  • -flex: about 5% cheaper than the standard variant of the same generation, for workloads that do not need full performance all the time.

Higher generation numbers are newer, and within a family, moving up a generation usually means equal or lower price with better performance. Going from m5 to m7i or m8g is an upgrade that barely needs analysis.

The t family: where the burstable model fits #

t4g and t3 guarantee only a baseline share of the CPU, with everything above it paid for in credits. The baseline depends on size: 10% of a vCPU for t3.micro, 20% for t3.small and t3.medium, 30% for t3.large. Credits accrue while idle and burn while busy, so the listed price is the real price only when average utilization stays below the baseline.

The good fits are clear: development and staging servers, low-traffic internal tools, and batch jobs with long idle gaps. A t4g.micro runs about $0.008 per hour, cheaper than the same-size t3 (about $0.010).

The bad fits are just as clear: services whose CPU sits above the baseline continuously. When credits run out, performance is clamped to the baseline — and in unlimited mode, which is on by default, you get surcharges instead of clamping. Sustained surcharges make a t instance more expensive than the same-size m. If “it ran fine for days, then suddenly slowed down” was gp2 credit exhaustion on EBS (see gp3 vs io2), on EC2 it is t credit exhaustion. A CPUCreditBalance graph scraping the floor means it is time to move beyond t instances.

m, c, r: the vCPU-to-memory ratio is the criterion #

At the same size, m, c, and r have the same vCPU count and differ only in memory. The ratio is the use case.

TypevCPUMemoryRatioHourly priceProfile
c8g.large24GiB1:2~$0.080Compute-heavy
m8g.large28GiB1:4~$0.090General purpose
r8g.large216GiB1:8~$0.118Memory-heavy

Read this from measurements, not from the price sheet. If CPU runs hot while more than half the memory sits idle, move to c; if memory fills up while the CPU idles, move to r. The c family suits web and API servers, build/CI, encoding, and game servers; r suits in-memory caches (Redis, Memcached), large JVM heaps, and analytics workloads. When unsure, start on m and let measurements decide. The comparison is sharpest at equal memory: when you need 16GiB, an r8g.large (2 vCPUs) is about $0.118 while an m8g.xlarge (4 vCPUs) is about $0.180. If the CPU is idle anyway, r delivers the same memory at two-thirds the price.

One caution: size determines more than CPU and memory. Network bandwidth and EBS bandwidth/IOPS limits are bound to the instance size. Provisioning a fast gp3 volume behind a small instance gets clipped at the instance limit, as covered in gp3 vs io2.

The architecture axis: Graviton, Intel, AMD #

Orthogonal to the family choice is the architecture axis. Within the same m8 generation, Graviton (m8g) is priced about 10% below Intel (m7i, m8i) per hour, and once generational performance gains stack on top, the price-performance gap widens further. An m8g.large is about $0.090 versus about $0.101 for m7i.large. AMD (a) is the middle option: same x86, binary-compatible, about 10% cheaper than Intel.

Graviton is ARM, so it needs a check before migrating. Interpreted languages (Python, Node.js, Ruby) and the JVM generally move as-is; native binaries and container images need ARM builds. Savings estimates and a migration checklist are in Migrating EC2 to Graviton. For new workloads, the price-efficient order is to evaluate Graviton first and fall back to x86 only when a dependency blocks you.

Everything else, only with an explicit need #

Families outside t, m, c, and r are like io2: chosen only when the requirement is explicit.

  • x, u (high memory): ratios of 1:16 and beyond, for large in-memory databases such as SAP HANA. Measured evidence that r is insufficient comes first.
  • i, d (storage): dense local NVMe/HDD, for distributed databases and search engines bottlenecked on local disk IOPS. Most workloads are fine on EBS.
  • p, g, inf, trn (accelerated): GPU and AI accelerator families. Which one you need is covered in Training vs Inference Servers and What Makes a GPU Server Different.

The selection order: measure first #

  1. Measure current consumption: check the CPU profile with CloudWatch CPUUtilization; memory is not in the default metrics, so attach the CloudWatch Agent. On t instances, watch CPUCreditBalance too.
  2. Turn on Compute Optimizer: it is free and produces account-wide, measurement-based findings on over- and under-provisioning with recommended types. Cleaning up idle instances overlaps with the standing checklist.
  3. Pick the family: low average CPU with intermittent spikes means t, balanced means m, and a measured skew means c or r.
  4. Pick the architecture and generation: check Graviton feasibility first, and take the latest generation unless something specific stops you.
  5. Start small and grow: resizing is a single reboot, so starting small and scaling up is cheaper than overprovisioning and never scaling down. Once long-term operation is settled, a Savings Plans commitment cuts the on-demand rate further.

Summary #

  • Read type names as family (workload), generation, and attributes (g=Graviton, i=Intel, a=AMD, d=local NVMe). Within a family, the latest generation is the default.
  • The t family is cheap only while average utilization stays below the baseline. Credit exhaustion and unlimited-mode surcharges are the signal to move to m.
  • m, c, and r are defined by vCPU-to-memory ratio (1:4, 1:2, 1:8). Move only after measurements show which side is the bottleneck.
  • Within a generation, Graviton runs about 10% cheaper than x86. For new workloads, evaluating Graviton first is the price-efficient order.
  • Size from CloudWatch and Compute Optimizer measurements, starting small. Remember that network and EBS limits are bound to instance size along with CPU and memory.
X