TL;DR: gp3 is ~20% cheaper per GB than gp2 and decouples performance from size: every gp3 volume gets 3,000 IOPS and 125 MB/s baseline no matter how small it is. Migration is a live, in-place modify-volume call — no downtime, no code changes. If you still have gp2 volumes, this is the closest thing AWS offers to free money.
The numbers
- gp2: ~$0.10/GB-month; IOPS = 3× volume size (min 100, burst 3,000)
- gp3: ~$0.08/GB-month; 3,000 IOPS + 125 MB/s included at any size; up to 16,000 IOPS ($0.005/IOPS-month above baseline) and 1,000 MB/s ($0.04/MB/s above 125)
Worked examples:
- 50 instances × 500 GB root volumes: $2,500/month on gp2 → $2,000 on gp3. $6,000/year saved by changing a dropdown.
- A database needing 5,000 IOPS on 300 GB of data: gp2 forces a 1.67 TB volume (
$167/month) just to reach the IOPS; gp3 does it with a 300 GB volume + provisioned IOPS ($40/month).
Do this
-
Find your gp2 volumes:
aws ec2 describe-volumes --filters Name=volume-type,Values=gp2 \ --query 'Volumes[].{id:VolumeId,size:Size,attached:Attachments[0].InstanceId}' -
Migrate live — no detach, no stop:
aws ec2 modify-volume --volume-id vol-0abc123 --volume-type gp3The modification runs in the background (minutes to hours by size); the instance keeps serving. Start with dev/test volumes, then batch through production during quiet hours.
-
Volumes over 1,000 GB: match performance explicitly. gp2 at 1,334 GB has a 4,002-IOPS baseline; on gp3 you'd provision the equivalent:
--iops 4000. Still usually cheaper — just not the full 20%. -
Make gp3 the default everywhere new: launch templates, Terraform (
type = "gp3"), CloudFormation, and AMI block-device mappings, so gp2 stops re-appearing.
Gotchas
- You can't shrink a volume. If a gp2 volume was over-sized just to buy IOPS, migrating to gp3 keeps the wasted gigabytes. Recovering them means creating a smaller volume and moving the data — a bigger job; do it opportunistically at replacement time.
- Performance during migration can dip slightly; there's also a 6-hour cooldown between successive modifications of the same volume.
- Very large/busy gp2 volumes (>1 TB) relied on a higher IOPS baseline — verify workload IOPS in CloudWatch (
VolumeReadOps/VolumeWriteOps) before assuming the gp3 baseline covers them.
Skip this if
- The volume needs sustained ultra-low latency and >16,000 IOPS — that's io2 territory, not gp3.
- The workload is sequential-throughput-heavy on huge datasets (big-data scratch space) — st1 HDD can be cheaper per GB.
- It's already gp3 (obviously) — then the remaining lever is right-sizing provisioned IOPS/throughput back to baseline where usage doesn't justify them.