Skip to main content

Cut your AWS EBS bill ~20% by migrating gp2 to gp3

· 4 min read
Founder, Dragon Fractal · ex-AWS engineer

Short version: AWS gp3 EBS volumes cost ~20% less per GB than gp2 ($0.08 vs $0.10 per GB-month in us-east-1) and include 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: a single modify-volume call. For most volumes it is free money. Here is how to find them, migrate them, and the one caveat to check.

Why gp3 is cheaper (and usually faster)​

gp2 pricing couples performance to size: you get 3 IOPS per GB, so the only way to get more IOPS on gp2 is to over-provision storage you do not need. gp3 decouples them:

gp2gp3
Storage$0.10 / GB-month$0.08 / GB-month (-20%)
Baseline IOPS3 IOPS/GB (burst to 3,000)3,000 included at any size
Baseline throughputscales with size125 MB/s included
Extra IOPS / throughputnot possibleprovision independently

(Prices are us-east-1 list; the ratio holds across regions.)

For a 500 GB volume that is $50/month to $40/month, i.e. $120/year saved, per volume, with equal or better performance. Multiply 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, then wait before re-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 normally still cheaper than the equivalent gp2, but check CloudWatch VolumeReadOps/VolumeWriteOps before assuming you need the headroom. Volumes ≤ ~1 TB with normal workloads are a straight 20% win.

Do it automatically​

Finding gp2 volumes and estimating the savings across every account and region by hand does not scale. That is exactly what Cloud Cost Analyzer's ebs-gp2-to-gp3-migration rule does: it flags every gp2 volume and estimates the monthly saving, alongside 89 other cost rules:

curl -sSL https://releases.dragonfractal.com/install.sh | sh
cca scan --provider aws

The agent runs in your environment with read-only access, so your AWS credentials never leave it. See the AWS setup and required IAM permissions

CLI Reference

  • aws ec2 modify-volume
  • aws ec2 describe-volumes
  • aws ec2 create-snapshot