awsebsstoragecost-optimization

EBS gp3 vs io2: when each makes sense

For 95% of production workloads, gp3 is the right choice (cheaper, performant enough). Use io2 only for over 16K IOPS sustained, 99.999% durability, or Multi-Attach. Here's the pricing math and the migration playbook.

The C3X Team··10 min read

Quick answer

For 95% of production workloads, gp3 is the right choice — it's cheaper, performant enough (up to 16K IOPS, 1000 MB/s), and handles most database workloads. Use io2 only when you need more than 16K IOPS sustained per volume, 99.999% durability, or Multi-Attach. io2 Block Express handles the extreme cases (256K IOPS).

The EBS volume type decision sounds technical but is mostly a cost decision. gp3 and io2 occupy different performance tiers at very different price points. Most teams use io2 in places where gp3 would work, and overpay 5-10x for capabilities they don't use.

This post walks through the actual specs, the pricing math, and the workload patterns that justify io2.

The two volume types at a glance

Specgp3io2io2 Block Express
Max IOPS per volume16,00064,000256,000
Max throughput1,000 MB/s1,000 MB/s4,000 MB/s
Max size16 TB64 TB64 TB
Durability99.8%-99.9%99.999%99.999%
Multi-AttachNoYesYes
Storage price$0.08/GB-mo$0.125/GB-mo$0.125/GB-mo

The pricing math at concrete sizes

1 TB volume, 5,000 IOPS

gp3 (5,000 IOPS = 2,000 above 3,000 baseline):

  • Storage: 1,024 × $0.08 = $81.92
  • IOPS: 2,000 × $0.005 = $10
  • Total: $91.92/month

io2:

  • Storage: 1,024 × $0.125 = $128
  • IOPS: 5,000 × $0.065 = $325
  • Total: $453/month

io2 is 5x more expensive for this workload. gp3 handles 5,000 IOPS easily.

1 TB volume, 16,000 IOPS (gp3 ceiling)

gp3 (max IOPS):

  • Storage: $81.92
  • IOPS: 13,000 × $0.005 = $65
  • Total: $146.92/month

io2:

  • Storage: $128
  • IOPS: 16,000 × $0.065 = $1,040
  • Total: $1,168/month

Still 8x more expensive for io2. At the gp3 IOPS ceiling, gp3 is dramatically cheaper.

1 TB volume, 50,000 IOPS (gp3 can't do this)

gp3 maxes at 16K IOPS per volume. To get 50K IOPS on gp3, you'd need 4+ volumes with software RAID (operational complexity).

io2:

  • Storage: $128
  • IOPS tier 1 (0-32K): 32,000 × $0.065 = $2,080
  • IOPS tier 2 (32K-64K): 18,000 × $0.046 = $828
  • Total: $3,036/month

At this performance level, io2 is required. The $3K/month is the cost of needing 50K IOPS in a single volume.

When you actually need io2

1. Sustained over 16K IOPS per volume

OLTP databases with high write throughput, latency-sensitive time-series databases, message queues at scale. Measure sustained IOPS on the current volume. If it's regularly above 16K, gp3 has hit its ceiling.

2. 99.999% durability requirement

Most workloads don't need this — application-level replication and database HA solve durability better than disk durability. But for single-instance databases without replication where data loss is catastrophic (some legacy systems, regulated financial systems), io2's 100x lower annual failure rate matters.

3. Multi-Attach

Shared storage across multiple instances in an Auto Scaling Group. Required for some HA database configurations (SAP HANA, Oracle RAC, etc.). gp3 doesn't support Multi-Attach; io2 does. If you need this feature, io2 is the only choice.

4. Single-volume large databases

Databases over 16 TB on a single volume. io2 supports 64 TB per volume. For databases that have grown past gp3's 16 TB limit without architectural sharding, io2 is required.

When gp3 wins (most cases)

General-purpose application storage

Web servers, application logs, ECS/EKS persistent volumes, development databases. All these run fine on gp3 with 3K-10K IOPS. The cost difference vs io2 is 5-10x.

Most production databases

Databases under 16K IOPS sustained — which is most of them. PostgreSQL, MySQL, MongoDB, SQL Server on standard workloads. gp3 handles them. Migration from io1/io2 to gp3 commonly cuts 50-70% of EBS costs.

Read-mostly databases

Reporting databases, analytics replicas, caching layers. Reads benefit from OS page cache and don't hammer EBS. gp3 baseline of 3K IOPS is often unused.

Container persistent volumes

Kubernetes PVCs typically have modest IOPS needs (config files, small databases, log buffers). gp3 default at 3K IOPS is usually sufficient.

The migration playbook

For accounts with significant io1/io2 spend that's not justified:

  1. Audit io2 volumes via Cost Explorer (filter by Usage Type = io2).
  2. For each io2 volume, measure actual IOPS via CloudWatch (VolumeReadOps + VolumeWriteOps).
  3. If max sustained IOPS is under 16K, candidate for gp3.
  4. If single-instance OLTP without replication, evaluate if 99.999% durability is needed.
  5. If Multi-Attach is unused, candidate for gp3.
  6. For candidates, modify volume type in-place (no downtime).

For deeper migration patterns, see gp2 to gp3 migration guide — same in-place technique applies for io2 to gp3.

Estimating with c3x

c3x reads the type, size, iops, and throughput attributes from Terraform and applies the right pricing:

resource "aws_ebs_volume" "db" {
  availability_zone = "us-east-1a"
  size              = 1024
  type              = "gp3"
  iops              = 16000
  throughput        = 1000
  encrypted         = true
}

c3x reports: $146.92/month (gp3, 1 TB, 16K IOPS, 1000 MB/s). Switching type to "io2" would change the estimate to $1,168/month. The cost delta is visible at PR time.

FAQ

When should I use io2 over gp3?

Three conditions. (1) You need more than 16,000 IOPS sustained per volume. (2) You need 99.999% durability vs gp3's 99.8%-99.9%. (3) Multi-Attach is required (sharing one volume across instances). For everyday production workloads, gp3 is the right choice.

What's the actual IOPS difference?

gp3 supports up to 16,000 IOPS per volume regardless of size. io2 supports up to 64,000 IOPS (256,000 on io2 Block Express). For workloads that need over 16K IOPS sustained, gp3 hits a ceiling and io2/io2 BX is the only AWS option.

How does pricing actually compare?

gp3 is $0.08/GB-month + provisioned IOPS above 3,000 baseline at $0.005/IOPS-month. io2 is $0.125/GB-month + tiered IOPS pricing starting at $0.065/IOPS-month for first 32K IOPS. For a 1 TB volume with 10K IOPS: gp3 = $80 + $35 = $115. io2 = $125 + $650 = $775. io2 is 7x more expensive at this size.

What is io2 Block Express?

io2 Block Express is a newer, higher-performance variant of io2 supporting up to 256K IOPS and 4,000 MB/s throughput per volume. Same per-GB and per-IOPS pricing as io2 but supports much higher provisioning. Right for the most demanding databases (large transactional, in-memory replacement).

Can I migrate from io1/io2 to gp3?

Yes, in place. AWS supports modifying volume type without downtime. The volume's data is migrated in the background while the instance keeps running. Some performance degradation during migration. Migration typically takes a few hours per TB depending on instance type.

What about gp2 vs io2?

gp2 is the legacy general-purpose SSD. It's almost always worse than gp3 (gp3 is 20% cheaper with better baseline performance). For high-IOPS, io2 vs gp2 isn't the right comparison — migrate gp2 to gp3 first, then evaluate if io2 is needed. See our gp2 to gp3 migration guide for the in-place migration.

Summary

Use gp3 by default. Use io2 only when you need over 16K IOPS sustained, 99.999% durability, or Multi-Attach. For most production workloads, the gp3-vs-io2 question is mechanical: check the IOPS requirement, pick the cheaper option that meets it. Audits of long-running fleets commonly find io2 volumes running 2-5K IOPS — those should be gp3 immediately.

For the broader EBS picture including legacy gp2, see when gp2 to gp3 actually saves money. For the EBS resource details, see aws_ebs_volume catalog page.

Try C3X on your own Terraform

Free and open source. No API key required. One command to install, one command to estimate.