Skip to content
RDS (non-Aurora)
Sub-page 2 of 9
Cost & billing mechanics · Free

Storage Type and Volume Size Are a Cost Decision You Make Once

Decision drivers
  • gp3 vs. io1 cost gap is ~4.4x at equivalent provisioned IOPS ($0.115/GB + $0.02/IOPS vs. $0.125/GB + $0.10/IOPS) — not a rounding difference, a default-changing one; io2 bills at the same flat rate as io1 on RDS (confirmed via AWS's launch announcement), so the same ~4.4x gap applies to io2 as well
  • io2 Block Express is the only tier with a 99.999% durability SLA and sub-millisecond target latency — io1 doesn't clear that bar despite also being "Provisioned IOPS"
  • Striping threshold (400GB open-source / 200GB Oracle) quadruples baseline performance for free — but crossing it under load costs hours of degraded I/O during re-striping
  • Storage only scales up — the billing baseline you cross into is permanent, with no shrink path
  • SQL Server doesn't support striping at all — this lever doesn't exist on that engine, so its storage-cost curve doesn't have this same inflection point

Production premise

RDS storage isn't one billing line — it's a provisioning curve you pick per volume, and the two families price IOPS completely differently. gp3 bundles a free baseline of 3,000 IOPS and 125 MiB/s into the base storage rate ($0.115/GB-month on RDS — a distinct, higher rate than EBS gp3's $0.08/GB-month, which is a different service entirely), then charges $0.02 per additional provisioned IOPS-month above that baseline. Provisioned IOPS io1 has no free baseline at all — every IOPS is billed from zero, at $0.10/IOPS-month, on top of a higher base storage rate ($0.125/GB-month). At 10,000 IOPS on a 1TB volume: gp3 costs roughly $255/month ($115 storage + $140 for 7,000 additional IOPS above baseline), while io1 costs roughly $1,125/month ($125 storage + $1,000 for 10,000 IOPS billed from zero) — io1 runs about 4.4x more expensive for the identical IOPS number, because you're paying for every IOPS instead of just the ones above the free tier. io2 Block Express bills at the identical flat rate to io1 on RDS — AWS's own launch announcement confirms "io1 volumes and io2 Block Express storage volumes are billed at the same rate" — so io2's extra durability and latency come at no per-IOPS premium over io1; this differs from EBS's io2, which uses tiered per-IOPS pricing that doesn't apply here.

Failure mode & inflection point

Provisioning io1/io2 out of habit — because it was once the safe recommendation, or because a template defaulted to it — for a workload that never actually needed io2 Block Express's sub-millisecond latency or 99.999% durability SLA. The inverse failure is just as real: growing an open-source-engine volume across the 400GB threshold (200GB for Oracle) without knowing it triggers automatic 4-way EBS striping. That's usually a win — baseline jumps from 3,000 to 12,000 IOPS and 125 to 500 MiB/s for free — but if it happens mid-migration or during a live cutover, the re-striping process itself can degrade I/O latency for several hours while it completes. And because RDS storage only ever scales up, whatever baseline cost you cross into is permanent — there's no shrink path to walk it back.

Production guardrail

Default to gp3 for essentially every workload — the ~4.4x cost gap over io1 at equivalent provisioned IOPS is too large to justify without a specific reason. The one deciding factor that overrides this default: a documented latency SLA that genuinely requires io2 Block Express's sub-millisecond target and 99.999% durability. When that factor applies, choose io2 over io1 outright — they bill at the identical rate on RDS, so io2's better durability (99.999% vs. io1's 99.8–99.9%) and IOPS ceiling come at no cost premium; there's no scenario where io1 is the better pick once you're past the gp3-vs-provisioned-IOPS decision. Absent that documented requirement, provisioning io1/io2 is close to always the wrong call. Separately: if you're on an open-source engine and expect to cross 400GB (200GB on Oracle) eventually, cross it during a planned maintenance window rather than organically under load — you get the free 4x IOPS/throughput bump without eating the re-striping penalty during a period that matters.