Short version: AWS gp3 EBS volumes cost about ~20% less per GB than gp2 ($0.08 vs $0.10 per GB-month in us-east-1) and includes 3,000 IOPS and 125 MB/s of baseline performance for free. You can convert a volume from gp2 to gp3 online, with no downtime and no snapshot with a single modify-volume call. For most volumes, it's a real savings. Here's how to find those volumes, migrate them, and the one caveat to keep in mind.
Why gp3 is cheaper (and usually faster)
gp2 pricing couples performance to its size: you get 3 IOPS per GB, so the only way to get more IOPS on gp2 is to over-provision storage you don't need. gp3 removes that coupling:
| gp2 | gp3 | |
|---|---|---|
| Storage | $0.10 / GB-month | $0.08 / GB-month (-20%) |
| Baseline IOPS | 3 IOPS/GB (burst to 3,000) | 3,000 included at any size |
| Baseline throughput | scales with size | 125 MB/s included |
| Extra IOPS / throughput | not possible | provision independently |
(Prices are us-east-1 list; the ratio holds across regions.)
For a 500 GB volume, that's $50/month to $40/month, i.e., $120/year saved, per volume, with equal or better performance. Now multiply this by every gp2 volume in every account.
Step 1 - Find your gp2 volumes
aws ec2 describe-volumes \
--filters Name=volume-type,Values=gp2 \
--query 'Volumes[].{ID:VolumeId,GiB:Size,AZ:AvailabilityZone,State:State}' \
--output table
Run it per region. EBS is regional, so a volume only shows up in its own region:
for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
echo "== $region =="
aws ec2 describe-volumes --region "$region" \
--filters Name=volume-type,Values=gp2 \
--query 'Volumes[].{ID:VolumeId,GiB:Size}' --output text
done
Step 2 - Migrate (online, no downtime)
Converting the type is a live modify-volume. The volume stays attached and readable/writable the whole time; it briefly enters an optimizing state:
aws ec2 modify-volume --volume-id vol-0abc123def456 --volume-type gp3
To convert everything in a region at once:
for vol in $(aws ec2 describe-volumes \
--filters Name=volume-type,Values=gp2 \
--query 'Volumes[].VolumeId' --output text); do
echo "migrating $vol"
aws ec2 modify-volume --volume-id "$vol" --volume-type gp3
done
No snapshot, no detach, no reboot. (AWS allows one modification per volume per 6 hours, so migrate and then wait before modifying the same volume.)
The one caveat: high-IOPS / high-throughput volumes
Because gp2 IOPS scale with size, a large gp2 volume may already deliver more than gp3's 3,000 baseline IOPS. A 2 TB gp2 volume provides 6,000 IOPS; if your workload actually uses them, migrate and provision matching performance on gp3:
aws ec2 modify-volume --volume-id vol-0abc123def456 \
--volume-type gp3 --iops 6000 --throughput 250
The first 3,000 IOPS and 125 MB/s are free; beyond that, extra IOPS are $0.005/provisioned-IOPS-month and extra throughput $0.040/MB/s-month. Even fully matched, gp3 is usually still cheaper than the equivalent gp2, but check CloudWatch VolumeReadOps/VolumeWriteOps before assuming you need the headroom. Volumes under ~1 TB with normal workloads are a straight 20% win.
Doing it across every account, automatically
Finding gp2 volumes and estimating the savings across every account and region by hand doesn't scale. It's one of the checks in a read-only CLI I built, Cloud Cost Analyzer. It flags every gp2 volume with the estimated monthly savings, alongside 89 other AWS cost rules:
curl -sSL https://releases.dragonfractal.com/install.sh | sh
cca scan --provider aws
It runs in your environment with read-only access, so your AWS credentials never leave it. Free tier if you want to try it on one account, and dashboards if you want to review or share reports.
Originally published on the Dragon Fractal Cloud Cost Analyzer blog.
Top comments (0)