The Amazon EBS io1/io2-to-gp3 policy flags Amazon Elastic Block Store (Amazon EBS) Provisioned IOPS SSD volumes (io1 and io2) that would run just as well on General Purpose SSD (gp3). It applies to volumes that need fewer than 16,000 IOPS and less than 1,000 MB/s of throughput, and that do not use Multi-Attach. For those volumes, gp3 often costs half as much or less, because gp3 storage and IOPS are both priced well below io1 and io2.
Attribute | Detail |
|---|---|
Cloud Provider | AWS |
Resource Type | Amazon EBS volumes ( |
Terraform Attribute |
|
Policy Thresholds | Under 16,000 IOPS, under 1,000 MB/s throughput, Multi-Attach not enabled |
Compliant Value |
|
Cost Impact | A 16 TiB volume at 16,000 IOPS costs about $1.4K/month on gp3 vs about $3K/month on io1 or io2 (US East, N. Virginia) |
Why This Policy Matters
How It Helps Reduce Cloud Costs
Amazon EBS io1 and io2 volumes bill for two things: provisioned storage and every provisioned IOPS. In US East (N. Virginia), AWS lists io1 and io2 storage at $0.125 per GB-month and IOPS at $0.065 per IOPS-month for the first 32,000 IOPS.
Amazon EBS gp3 volumes use a cheaper model. Storage is $0.08 per GB-month, and every gp3 volume includes 3,000 IOPS and 125 MB/s at no extra charge. Additional gp3 IOPS cost $0.005 per IOPS-month, a small fraction of the io1 and io2 IOPS rate.
Many io1 and io2 volumes were created before gp3 existed, or were chosen because "provisioned IOPS" sounded like the safe option for a database. When the workload needs fewer than 16,000 IOPS, gp3 can provision the same IOPS directly.
This policy targets a pricing gap, not a performance gap. A volume that fits within the thresholds pays a premium for io1 or io2 features it does not use.
Potential Savings
The Amazon EBS io1/io2-to-gp3 saving comes from two lower rates at once: about 36% less per GB of storage and about 92% less per provisioned IOPS above the gp3 baseline.
Using AWS list prices for US East (N. Virginia), a 16 TiB volume with 16,000 IOPS costs roughly $3,090 per month on io1 or io2. The same volume on gp3 with 16,000 IOPS and 1,000 MB/s costs roughly $1,410 per month. That is about 54% lower.
The saving grows as the IOPS-to-storage ratio rises. Small volumes with high provisioned IOPS see the largest percentage drop, because the io1 and io2 IOPS charge dominates their bill.
Very large volumes with low provisioned IOPS see a smaller saving. For those volumes, the saving trends toward the 36% storage price difference.
Implementation Guide
Infrastructure-as-Code Example (Terraform)
The following examples show an Amazon EBS volume provisioned as io2 for a database, and the corrected gp3 configuration.
Non-compliant configuration: Amazon EBS volume on io2 within gp3 limits
This 2,000 GiB io2 volume with 8,000 IOPS costs about $770 per month in US East (N. Virginia). This is a common source of wasted spend. The workload needs well under 16,000 IOPS and does not use Multi-Attach, so io2 adds cost without adding anything the workload uses.
Compliant configuration: Amazon EBS volume on gp3
The same volume on gp3 with 8,000 IOPS and 500 MB/s costs about $200 per month, roughly 74% less. The throughputattribute is only valid when type is gp3. Set it from observed throughput, not from a guess.
For io1 and io2 volumes, throughput is not a separate Terraform attribute. It scales with provisioned IOPS. That is why the gp3 configuration needs an explicit throughput value when the workload needs more than the 125 MB/s gp3 baseline.
Volumes with multi_attach_enabled = true are out of scope. Amazon EBS Multi-Attach is only supported on io1 and io2, so those volumes must stay on a Provisioned IOPS type.
Step-by-Step Fix Instructions
Search Terraform configuration for every
aws_ebs_volumeresource withtype = "io1"ortype = "io2".Check other places io1 and io2 can appear: the
volume_typeargument inroot_block_deviceandebs_block_deviceblocks onaws_instance, and inblock_device_mappingsonaws_launch_template.Exclude any volume with
multi_attach_enabled = true, and any volume withiopsof 16,000 or more.For each remaining volume, review CloudWatch
VolumeReadOps,VolumeWriteOps,VolumeReadBytes, andVolumeWriteBytesto find peak IOPS and throughput over at least two weeks.Change
typeto"gp3". Setiopsto the observed peak plus headroom, and setthroughputif the workload needs more than 125 MB/s.Run
terraform planand confirm the change onaws_ebs_volumeis an in-place update, not a replacement. Amazon EBS Elastic Volumes changes the volume type without detaching the volume.Apply during a low-traffic window, then watch the volume move through the
modifyingandoptimizingstates tocompleted.Add Infracost to CI/CD so any new io1 or io2 volume within the policy thresholds is flagged in the pull request before it merges.
Best Practices
Set
type = "gp3"as the default in shared Terraform modules. Require a documented latency, durability, or Multi-Attach reason before a module accepts io1 or io2.Size gp3
iopsandthroughputfrom CloudWatch metrics. Do not copy the old io1 or io2iopsvalue without checking actual use.Migrate non-production volumes first, then production volumes in batches. Wait for each Elastic Volumes modification to finish before changing the same volume again.
This policy is not a fit for every database. Workloads that depend on io2 sub-millisecond latency or 99.999% durability should stay on io2.
Tools and Scripts
How does Infracost detect io1 and io2 volumes that fit gp3?
The Amazon EBS io1/io2-to-gp3 policy is available in Infracost, including in the free trial. When Infracost runs in CI/CD, it checks Amazon EBS volumes in each pull request. It flags io1 and io2 volumes that fall within the policy thresholds in the PR comment, with the file and line to change.
This catches an oversized volume type before the volume exists, when the fix is a small change in the same pull request. Infracost also scans connected repositories for existing violations. FinOps and platform teams can then burn down that backlog and track progress on a burndown chart.
Teams can set the policy to warn engineers or to block pull requests that fail it, depending on how strictly they want to enforce gp3 as the default.
To list io1 and io2 volumes in the current region with the AWS CLI:
To migrate one volume in place outside Terraform:
If the volume is managed by Terraform, update type in code as well. Otherwise the next terraform apply will try to change the volume back to io1 or io2.
Examples of Impact
Illustrative example: a fleet of database volumes. A platform team runs 20 Amazon EBS io1 volumes of 500 GiB each, with 5,000 IOPS per volume. On io1, each volume costs about $388 per month, or about $7,750 for the fleet. On gp3 with 5,000 IOPS and 125 MB/s, each volume costs about $50, or about $1,000 for the fleet. That saves roughly $81,000 per year.
Illustrative example: a large volume near the threshold. A 16 TiB io2 volume with 16,000 IOPS costs about $3,090 per month. On gp3 with matching IOPS and 1,000 MB/s, it costs about $1,410. That is still a saving of about $1,680 per month on a single volume.
The higher a volume's provisioned IOPS relative to its size, the larger the share of its bill this policy removes.
(These are illustrative scenarios using published US East (N. Virginia) list prices, not specific customer accounts.)
Considerations and Caveats
gp3 is the right default for most Amazon EBS block storage, but io2 still earns its price for a narrow set of workloads.
Latency: io2 Block Express targets sub-millisecond average latency. gp3 targets single-digit millisecond latency, which is enough for most applications but not for every high-throughput database.
Durability: io2 is designed for 99.999% durability. gp3 and io1 are designed for 99.8% to 99.9%. Moving io2 to gp3 lowers durability, so confirm snapshot and backup coverage first.
Multi-Attach: Amazon EBS Multi-Attach only works on io1 and io2. Volumes shared across instances cannot move to gp3.
Thresholds are conservative: The 16,000 IOPS and 1,000 MB/s thresholds match gp3's original limits. AWS raised gp3 maximums in September 2025, so larger volumes may also fit gp3, but those need case-by-case review.
Provider-specific: This policy targets Amazon EBS through the
aws_ebs_volumeresource. Azure managed disks and Google Cloud persistent disks use different tiers and attribute names.
Related Policies and Concepts
Amazon EBS - consider upgrading gp2 volumes to gp3: the companion Block Storage policy that moves older General Purpose volumes to gp3.
Amazon EBS - consider upgrading io1 volumes to io2: the right policy for io1 volumes that do need Provisioned IOPS, since io2 offers higher durability at the same price.
RDS - consider upgrading gp2 storage type to gp3: the same storage-class discipline applied to Amazon RDS instance storage.
Azure Disk Storage - consider updating Premium SSD disk to v2: the Azure equivalent of separating disk performance from disk size to cut cost.
How Migrating gp2 to gp3 EBS Volumes Cuts Storage Costs by 20%: a planned Infracost resource article on gp3 pricing and in-place Amazon EBS migration, the same mechanics this policy relies on.
Frequently Asked Questions (FAQs)
Is this policy supported in Infracost?
Yes. The Amazon EBS io1/io2-to-gp3 policy is supported in Infracost and available in the free trial. Infracost flags io1 and io2 volumes that fit gp3 in pull requests, so the team can change the volume type before the volume is created.
Can this policy be customized?
Yes. Teams can configure how Infracost enforces the Amazon EBS io1/io2-to-gp3 policy. For example, a finding can warn engineers or block the pull request.
Does Infracost automatically fix violations?
Infracost reports Amazon EBS io1 and io2 volumes that fit gp3 in the pull request, with the file and line to change. Changing the Amazon EBS volume type should still be reviewed by the team, because latency and durability needs differ by workload.
Is this policy cloud-agnostic?
No. The Amazon EBS io1/io2-to-gp3 policy targets AWS through the aws_ebs_volume Terraform resource. Azure managed disks and Google Cloud persistent disks have their own performance tiers with different resource and attribute names.
How often should I review Amazon EBS Provisioned IOPS volumes?
Teams running Infracost in CI/CD get an Amazon EBS volume type check on every pull request that touches an Amazon EBS volume. For existing io1 and io2 volumes, a quarterly review of CloudWatch IOPS and throughput metrics is a reasonable cadence.
Does changing an Amazon EBS volume from io1 or io2 to gp3 require downtime?
No. Amazon EBS Elastic Volumes changes an io1 or io2 volume to gp3 in place, without detaching the volume or stopping the instance. The Amazon EBS volume stays in use while it moves through the modifying and optimizing states.
Why are Multi-Attach volumes excluded from the Amazon EBS io1/io2-to-gp3 policy?
Amazon EBS Multi-Attach, which lets one volume attach to several instances, is only supported on io1 and io2. A Multi-Attach volume cannot move to gp3, so the Amazon EBS io1/io2-to-gp3 policy does not flag it.
Create Free Account
This policy is supported in Infracost and available in the free trial. Sign up today and scan your code using our entire library of FinOps policies.