This FinOps policy flags Amazon Relational Database Service (Amazon RDS) instances still running on General Purpose SSD (gp2) storage and recommends migrating to General Purpose SSD (gp3), the newer general-purpose volume type. gp3 storage costs up to 20% less per GiB than gp2, and it decouples IOPS and throughput from allocated storage size, so teams stop paying for extra capacity they only added to reach a performance target. This applies to any RDS instance on MySQL, MariaDB, PostgreSQL, Oracle, Db2, or SQL Server that is still configured with storage_type = "gp2".
Attribute | Detail |
|---|---|
Cloud Provider | AWS |
Resource Type | Amazon RDS DB instance storage |
Terraform Attribute |
|
Compliant Value |
|
Cost Impact | Up to 20% lower price per GiB than gp2, with IOPS and throughput no longer tied to allocated storage size |
Why This Policy Matters
How It Helps Reduce Cloud Costs
General Purpose SSD (gp2) volumes tie IOPS to allocated storage size, at a rate of 3 IOPS per GiB, with a 100 IOPS floor. A 200 GiB gp2 volume gets only 600 baseline IOPS, and volumes under 1 TiB can burst to 3,000 IOPS using a credit balance that depletes under sustained load.
gp3 decouples performance from capacity. Below the per-engine allocated storage threshold, every gp3 volume includes a baseline of 3,000 IOPS and 125 MiB/s of throughput at no extra cost, regardless of size. At or above that threshold, most engines get a higher striped baseline of 12,000 IOPS and 500 MiB/s.
This makes gp2 a common source of quietly under-provisioned RDS storage. A team that needs more IOPS than gp2's size-linked formula provides has no option but to over-allocate storage capacity it does not actually need, just to reach an acceptable performance floor.
On top of the performance change, AWS prices gp3 at up to 20% less per GiB than gp2. That discount applies to every gp3 volume, independent of whether the workload ever uses the additional headroom.
Potential Savings
Savings come from two independent sources: the per-GiB price difference, and the ability to stop over-allocating storage purely to buy IOPS. Both apply the moment storage_type changes from gp2 to gp3.
Order of magnitude, a database that was sized well above its actual data footprint solely to hit a gp2 IOPS target can often be shrunk back toward its real storage need after migrating, compounding the 20% per-GiB discount with a smaller footprint. A database that was already sized correctly for its data still captures the flat 20% reduction with no other change required.
This is a configuration-only saving, not a usage reduction, which is what makes it low risk to apply broadly across a fleet of RDS instances.
Implementation Guide
Infrastructure-as-Code Example (Terraform)
The following examples show an RDS instance provisioned with gp2 storage, and the corrected configuration using gp3.
Non-compliant configuration: RDS instance on gp2 storage
This 200 GiB gp2 volume is capped at 600 baseline IOPS, well below what most production workloads need without provisioning far more storage than the orders database actually uses. This is a common source of wasted spend on databases sized for performance rather than capacity.
Compliant configuration: RDS instance on gp3 storage
Below the 400 GiB threshold that applies to PostgreSQL, MySQL, MariaDB, and Db2 (SQL Server has no such threshold), gp3 defaults to the 3,000 IOPS / 125 MiB/s baseline without needing an explicit iops or storage_throughput value. This 200 GiB volume gets the same baseline that a gp2 volume would only reach at nearly 1 TiB. Infracost includes a named RDS gp2-to-gp3 FinOps policy that flags this exact pattern in pull requests, so the team sees the recommendation before the instance is ever created.
Step-by-Step Fix Instructions
List every
aws_db_instanceresource in Terraform state withstorage_type = "gp2".Confirm the DB engine and version support gp3; AWS made gp3 available across all current RDS engines starting in November 2022.
Change
storage_typeto"gp3".If
allocated_storageis at or above the per-engine threshold (400 GiB for PostgreSQL, MySQL, MariaDB, and Db2, no threshold for SQL Server), decide whether to setiopsandstorage_throughputexplicitly or accept the higher striped baseline.Run
terraform planand confirm the change is an in-place modification, not a replacement; gp2-to-gp3 is a supported storage-type change on an existing RDS instance.Apply the change. RDS enters a
storage-optimizationstatus during the migration; the instance stays available, though latency can be briefly elevated.Add Infracost to CI/CD so any future
aws_db_instanceresource withstorage_type = "gp2"gets flagged before it merges.
Best Practices
Set
storage_type = "gp3"as the default in shared RDS Terraform modules so new instances never launch on gp2 in the first place.Only set explicit
iopsorstorage_throughputvalues onceallocated_storageclears the per-engine threshold; below it, those attributes cannot be modified from the fixed baseline.This policy does not apply to instances that already require provisioned IOPS storage (
io1orio2) for a latency-sensitive, business-critical workload; gp3 is a general-purpose tier, not a replacement for provisioned IOPS.Batch gp2-to-gp3 migrations with other planned maintenance windows for production databases, even though the change itself does not require downtime.
Tools and Scripts
This policy check is available in Infracost, including in the free trial. Infracost's FinOps policy library includes a named RDS gp2-to-gp3 check that flags aws_db_instance resources with storage_type = "gp2" in pull requests, giving the team a chance to switch to gp3 before the instance is created. Infracost's AutoFix feature can also generate a pull request with this exact storage_type change already drafted, when AutoFix is enabled for the policy; a person still reviews and merges it.
This turns a one-time cleanup into an ongoing check. Infracost enables platform and FinOps teams to track how many RDS instances remain on gp2 across the organization and burn that number down incrementally, with a trend line to report on.
To check the storage type of existing RDS instances using the AWS CLI:
Examples of Impact
Illustrative example: oversized for IOPS, not data. A platform team provisions a 1 TiB gp2 volume for a 200 GiB production database, solely to reach the 3,000 IOPS baseline that gp2 requires a volume that large to deliver. Migrating to gp3 provides the same 3,000 IOPS baseline well under 400 GiB, letting the team shrink the volume back toward the storage the database actually uses.
Illustrative example: fleet migration during maintenance windows. A team with dozens of gp2-backed RDS instances migrates them to gp3 in batches during scheduled maintenance windows. Each migration completes without downtime, and the 20% per-GiB discount applies across the fleet without a single high-risk cutover.
(These are illustrative, composite scenarios, not specific customer accounts.)
Considerations and Caveats
Per-engine IOPS and throughput threshold: for PostgreSQL, MySQL, MariaDB, and Db2,
iopsandstorage_throughputcannot be set on gp3 below 400 GiB of allocated storage; the fixed baseline of 3,000 IOPS / 125 MiB/s applies instead. SQL Server has no such threshold.Higher striped baseline at scale: at or above the 400 GiB threshold, most engines get a baseline of 12,000 IOPS and 500 MiB/s through volume striping.
Provider-specific: this policy targets
storage_typeon theaws_db_instanceresource; equivalent managed database storage tiers on other clouds use different resource and attribute names.Not a substitute for provisioned IOPS: workloads with proven, consistent, latency-sensitive demand may still be better served by
io1orio2storage rather than gp3.Storage-only change: this policy affects storage cost and performance only. It does not change instance class, Multi-AZ configuration, or backup retention, each of which carries its own separate cost impact.
Related Policies and Concepts
EMR - consider upgrading gp2 storage type to gp3: the same storage-type discipline applied to a different Compute-group service in Infracost's FinOps policy library.
PostgreSQL - consider using backup retention in non-production projects: a related Compute-group policy addressing RDS-adjacent configuration hygiene rather than usage-based waste.
RDS Cluster - consider enabling CloudWatch log exports: a Compute-group policy covering operational visibility for the same class of managed database infrastructure.
"How to Enforce Cloud Cost Policies in Your CI/CD Pipeline": a planned Infracost resource article covering the broader workflow of catching cost policy violations like this one at the pull request stage, before they reach production billing.
Frequently Asked Questions (FAQs)
Is this policy supported in Infracost?
Yes. Infracost's FinOps policy library includes a named RDS gp2-to-gp3 check that flags aws_db_instance resources with storage_type = "gp2" in pull requests, so the team can switch to gp3 before the instance launches. This check is available in the free trial and all paid plans.
Can this policy be customized?
Yes. Teams can adjust the policy's scope in Infracost, for example limiting the check to specific database engines or excluding instances that have a documented reason to remain on gp2.
Does Infracost automatically fix violations?
Partially. Infracost's AutoFix feature can generate a pull request that proposes changing storage_type from gp2 to gp3 on an aws_db_instance resource, including the underlying policy context. A person still reviews and merges the change; Infracost does not merge it automatically.
Is this policy cloud-agnostic?
No. This specific policy targets Amazon RDS and the aws_db_instance Terraform resource. Other clouds' managed database services have their own storage-tier tradeoffs, but the resource and attribute names differ.
How often should I review RDS storage type compliance?
Teams running Infracost in CI/CD get a check on every pull request that touches an aws_db_instance resource. For instances already running, a quarterly review alongside other planned maintenance is a reasonable cadence for catching any that predate gp3 adoption.
Does switching from gp2 to gp3 require downtime?
No. Amazon RDS supports changing storage_type from gp2 to gp3 as an in-place modification. The instance enters a storage-optimization status during the change and remains available, though latency can be briefly elevated for very large volumes.
What is the minimum allocated storage needed to set custom IOPS and throughput on gp3?
For PostgreSQL, MySQL, MariaDB, and Db2, allocated_storage must reach 400 GiB before iops and storage_throughput can be set explicitly. Below that, gp3 uses a fixed baseline of 3,000 IOPS and 125 MiB/s. SQL Server has no such threshold.
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.