RDS Instance Classes Compared: db.t vs db.m vs db.r

6 min read

RDS instance classes look like EC2 types with a db. prefix, so the rules seem identical. The selection criteria are not. In a database, memory is the cache, so the line between m and r tilts toward memory more than it does on EC2 — and t-family credit exhaustion translates directly into latency for every service using the database. The conclusion up front: use db.t4g for development and staging, start production on db.m8g, and move to db.r8g when measurements show the working set exceeding memory. EC2-side naming rules and family basics are covered in EC2 Instance Families Compared. Prices are for us-east-1, MySQL, Single-AZ on-demand.

Same naming rules, engine-specific availability #

A db.m8g.large is the same hardware as an EC2 m8g.large, and you read the family (t, m, r), generation digit, and attribute letters (g=Graviton, i=Intel) the same way. Two things differ.

  • Available classes depend on the engine and version. The current Graviton4 generation (db.m8g, db.r8g) is supported on PostgreSQL, MySQL, and MariaDB, with version floors (MySQL 8.0.32+, PostgreSQL 13.8+, and so on). Oracle and SQL Server have their own class lists. Before deciding on a class, confirm it actually appears as an option for your engine and version in the console.
  • There is no c family. Databases have no demand for a 1:2 vCPU-to-memory ratio, so the practical choices are t, m, r, and high-memory (db.x2g).

Why the same hardware costs twice as much #

An EC2 m8g.large runs about $0.090 per hour; a db.m8g.large on RDS MySQL runs about $0.168. The difference is the management fee. Automated backups and point-in-time recovery, minor version patching, Multi-AZ failover orchestration, and snapshot management are folded into the instance price. Running the database yourself on EC2 halves the hardware bill but hands you all of that operational work, so a naive price comparison does not hold.

Watch what gets added on top. Multi-AZ doubles the instance charge for the standby, and storage and provisioned IOPS are billed separately. RDS storage now defaults to gp3 and the selection logic matches EBS, so the criteria in gp3 vs io2 apply as-is. Backup and operations practice is covered in AWS Intermediate #4.

db.t: right for development, borrowed time in production #

db.t4g and db.t3 use the same burstable model as EC2’s t family. A db.t4g.micro runs about $0.016 per hour, the cheapest option, and it is free-tier eligible — the right answer for learning and testing.

Production is a different story. When an application server exhausts its credits, that one server slows down; when a database exhausts its credits, the latency spreads to every service that reads from it. The moment traffic grows enough for queries to queue up is exactly the moment CPU crosses the baseline, so the design guarantees you are slowest when you are busiest. If production is running on db.t, set an alarm on CPUCreditBalance and move to db.m as soon as the depletion pattern appears.

db.m vs db.r: the buffer pool decides #

ClassvCPUMemoryHourly priceProfile
db.t4g.micro21GiB~$0.016Dev/testing
db.m8g.large28GiB~$0.168General purpose
db.r8g.large216GiB~$0.239Memory-heavy

In a database, memory is the buffer pool and cache. RDS MySQL assigns 75% of instance memory to the InnoDB buffer pool by default, so the class’s memory effectively is the cache size. If the frequently read data (the working set) fits in the buffer pool, reads are served from memory; whatever does not fit spills over into disk I/O.

The deciding metric is therefore not CPU but that spillover. When FreeableMemory sits pinned at the bottom and ReadIOPS climbs faster than traffic, the working set has outgrown memory. At that point, between scaling up db.m and moving to db.r, r is cheaper at equal memory. When you need 16GiB, a db.r8g.large is about $0.239 while a db.m8g.xlarge (4 vCPUs) is about $0.336. If the database’s CPU is idle, r delivers the same cache for about 70% of the price. Conversely, if a write-heavy workload is bottlenecked on CPU and commit throughput, scaling up m is the right move.

Moving to Graviton: easier than on EC2 #

On EC2, a Graviton migration meant checking for ARM builds (see the checklist). RDS is different: AWS manages the engine binaries, so there is nothing to change on the application side. Clients connect over the same protocol as before, so going from db.m6i to db.m8g is a single class change. About the only reason to stay on Intel classes (db.m6i and friends) is an engine or version that does not yet support the Graviton class.

Generation upgrades are the same operation. A class change involves a restart and therefore downtime, but with Multi-AZ the standby is modified first and a failover follows, cutting the interruption to tens of seconds. The hands-on procedure is covered in AWS in Practice #2.

The selection order: measure first #

  1. Measure current consumption: watch CloudWatch CPUUtilization, FreeableMemory, ReadIOPS/WriteIOPS, and DatabaseConnections. For query-level bottlenecks, use Performance Insights (on by default, 7 days free). First rule out problems that tuning would fix — missing indexes, N+1 queries — before papering over them with a bigger class.
  2. Split environments: db.t4g is enough for development and staging, and stopping them nights and weekends cuts the bill further (see the standing checklist).
  3. Pick the production class: start on db.m8g, and move to db.r8g when FreeableMemory bottoms out and ReadIOPS spikes. Only genuinely oversized in-memory requirements that outgrow r justify high-memory classes like db.x2g.
  4. Pick the size: anchor on the smallest memory that fits the working set in the buffer pool, start small, and grow. Multi-AZ and storage IOPS are decided separately from the class.
  5. Commit: for production databases with a settled long-term future, Reserved Instances cut the on-demand rate substantially. Graviton4 classes (db.m8g, db.r8g) are covered too.

Summary #

  • RDS classes follow EC2 naming with a db. prefix, but availability varies by engine and version — check the console’s actual options first.
  • The same hardware costs about twice as much because management is included. Multi-AZ doubles it again, and storage and IOPS are separate.
  • db.t is for development and testing. Production credit exhaustion spreads latency to every dependent service, so treat it as borrowed time with a CPUCreditBalance alarm.
  • db.m and db.r are separated by the buffer pool. FreeableMemory at the bottom plus a ReadIOPS spike is the signal, and at equal memory, r beats scaling up m on price.
  • Graviton migration is easier on RDS than on EC2: one class change, no application changes, and with Multi-AZ the interruption is tens of seconds.
X