By Bill Gleeson · Updated July 2026

Storage is usually 20–30% of an AWS bill, and it’s the part with the cleanest, lowest-risk savings on the platform. Almost every account is overpaying in the same few ways: GP2 volumes where GP3 would cost less and perform better, expensive provisioned-IOPS (io1/io2) storage that almost no workload actually needs, Aurora databases paying per-request for I/O they could get flat-rate, and S3 buckets where objects sit in Standard for years untouched.

This guide compares every storage option that matters for cost, gives you the break-even math, and links out to the deep-dive on each. If you only read one table, read the decision framework near the bottom.

What this guide covers

  • EBS volumes: GP2 vs GP3 vs io1 vs io2 — the master comparison
  • The #1 win: GP2 → GP3 (~20% cheaper, 10× the IOPS on small volumes)
  • Drop io1/io2 for GP3 (60–87% cheaper; rarely needed)
  • RDS storage: io1/io2 → GP3 (cut IOPS cost up to 60%)
  • Aurora: Standard vs I/O-Optimized (30–40% off for I/O-heavy workloads)
  • S3: Intelligent-Tiering (up to 68%; and when it’s a trap)
  • OpenSearch and managed-service EBS markups (15–20%)
  • Decision framework: which storage should I use?

The AWS storage hierarchy: where the money goes

Block storage (EBS) is the biggest single line for most accounts, followed by object storage (S3) and database storage (Aurora/RDS). The cost levers are different for each, but the principle is the same: you are almost always paying for a performance tier you don’t use. GP2 charges you for storage to indirectly buy IOPS. io1/io2 charges per provisioned IOPS whether you use them or not. Aurora Standard charges per I/O request. Each has a cheaper alternative that gives equivalent or better performance for typical workloads.


EBS volumes: GP2 vs GP3 vs io1 vs io2

EBS is where most storage waste lives. Here’s the full comparison (indicative us-east-1 list pricing — verify in your region):

Volume type Class Storage $/GB-mo IOPS IOPS pricing Max throughput When to use
gp2 SSD $0.10 3 IOPS/GB (burst to 16K) Bundled in storage price Up to 250 MiB/s Legacy — migrate to gp3
gp3 SSD $0.08 3,000 baseline, up to 16,000 3,000 free, then $0.005/IOPS 125 MiB/s baseline, up to 1,000 Default for ~95% of workloads
io1 SSD $0.125 Up to 64,000 $0.065/provisioned IOPS Up to 1,000 MiB/s Rare — sub-ms latency needs
io2 / io2 Block Express SSD $0.125 Up to 256,000 $0.065/provisioned IOPS Up to 4,000 MiB/s Mission-critical, multi-attach
st1 HDD $0.045 Up to 500 MiB/s Big data, data warehouses
sc1 HDD $0.015 Up to 250 MiB/s Infrequent access (colder than st1)

Two things jump out: gp3 is cheaper than gp2 and decouples IOPS from size, and io1/io2 provisioned IOPS cost ~13× more per IOPS than gp3 ($0.065 vs $0.005). Almost all the savings come from those two facts.


The #1 win: switch GP2 → GP3

GP3 replaced GP2 as the default in 2020, yet most accounts still run thousands of GP2 volumes. GP3 is roughly 20% cheaper per GB and gives a flat 3,000 IOPS baseline regardless of volume size.

The performance difference is most dramatic on small volumes. A 100 GiB GP2 volume gets only 300 IOPS (3 per GiB). The same volume on GP3 gets 3,000 IOPS — 10× more — for 20% less money. There is almost no scenario where a small volume should stay on GP2.

On large volumes the win is purely price: a 1 TiB volume drops from ~102/mo(GP2)to 82/mo (GP3), with comparable performance.

Deep dive: Full side-by-side, cost math, and CLI + at-scale migration steps → GP2 vs GP3 on AWS: Save 20% and Get 3,000 IOPS

The catch: there’s functionally no catch. GP2→GP3 is a volume modification, not a rebuild — it can be done with no downtime in most cases. The only reason it doesn’t get done is volume: enterprises have thousands of volumes and nobody owns the task. (That’s the gap automation fills — see below.)


The #2 win: drop io1/io2 for GP3

Provisioned-IOPS storage (io1/io2) is priced for the rare workload that needs guaranteed single-digit-millisecond latency and very high IOPS — large OLTP databases, for example. In practice, the vast majority of io1/io2 volumes were provisioned years ago and never re-evaluated.

GP3 delivers up to 16,000 IOPS — more than enough for nearly all workloads — at a fraction of the cost. The IOPS charge alone tells the story: a volume that needs 10,000 IOPS costs ~650/moinIOPSonio1 * *(0.065 × 10,000) versus **~$35/mo on GP3 (3,000 free + 7,000 × $0.005). That’s a ~95% reduction on the IOPS line, before the cheaper per-GB storage.

AWS’s own guidance is that GP3 can replace io1/io2 for most workloads. You only genuinely need io1/io2 if you require sustained IOPS above 16,000, sub-millisecond latency guarantees, or EBS Multi-Attach.

Deep dive: Performance comparison, a real 4-node Oracle migration, and the pre-flight checklist → GP3 vs io1/io2 on AWS: Cost, IOPS & When to Switch


RDS storage: io1/io2 → GP3

Managed databases inherit the same problem. Many RDS instances were created on io1/io2 storage and left there. Because RDS abstracts the underlying EBS, the waste is invisible until you look — and the savings can be the largest single-line cut in your storage bill, since RDS volumes tend to be large and heavily provisioned.

The pattern is identical to standalone EBS: if the instance doesn’t need sustained IOPS above 16,000 (most don’t), GP3 storage delivers equivalent performance at a fraction of the cost.

Deep dive: How to identify RDS io1/io2 candidates and migrate without downtime → io1/io2 to GP3 on RDS: Cut IOPS Cost Up to 60%


Aurora: Standard vs I/O-Optimized

Aurora Standard charges two things for storage: a per-GB rate and a per-I/O-request rate ($0.20 per million requests). For I/O-heavy databases — e-commerce, analytics, IoT — the I/O charges balloon and quietly become the largest part of the Aurora bill.

Aurora I/O-Optimized flips the model: storage costs 2.25× more per GB ($0.225 vs Standard’s $0.10), but I/O requests are included. Compute pricing is unchanged. The decision is pure math:

  • If your I/O charges are less than ~25% of total Aurora spend, stay on Standard.
  • If they’re more than ~25%, switch to I/O-Optimized — typical savings are 30–40% for genuinely I/O-heavy workloads.

You can see your I/O share directly in Cost Explorer (filter the Aurora cluster’s costs by the “I/O requests” usage type) or via CloudWatch.

Deep dive: Break-even formula, a worked example, and how to switch → Aurora I/O-Optimized vs Standard: Which Is Cheaper in 2026?


S3: Intelligent-Tiering (and when it’s a trap)

S3 Intelligent-Tiering automatically moves objects between access tiers based on usage: objects not accessed for 30 days drop to a cheaper tier (~40% lower), and after 90 days to a colder tier (~68% lower). Critically, the instant-access tiers have no retrieval fee — performance is unchanged for the tiers that matter day-to-day. AWS reports customers have saved more than $6 billion versus S3 Standard since Intelligent-Tiering launched in 2018.

The only cost is a small monitoring fee: $0.0025 per 1,000 objects per month — applied only to objects larger than 128 KB (smaller objects are exempt and stay in Frequent Access). For most workloads the savings dwarf this fee many times over.

When it’s a trap: Intelligent-Tiering is a bad fit for buckets with a very small number of very large objects, or for data you know is archival (lifecycle rules to Glacier are cheaper). The opt-in Archive tiers also carry multi-hour retrieval, so don’t enable them for data you need fast. But for the common case — application uploads, logs, user content of unknown access pattern — Intelligent-Tiering is almost always a net win.

Deep dive: The five tiers, pricing, and three ways to enable it → S3 Intelligent-Tiering: Does It Actually Save Money?


OpenSearch and managed-service EBS markups

Managed services add a second layer of waste: the EBS storage they attach is often marked up over standard EBS, and the recommended instance sizes are usually oversized. OpenSearch (and Elasticsearch) clusters are the classic example — OpenSearch EBS storage runs roughly 53% above standard GP3 pricing, with similar markups on provisioned IOPS and throughput.

The two levers here are right-sizing (matching instance type/volume to actual CPU and memory usage — typically a 15–20% cut) and architecture choice (Graviton-based instances like m6g vs. their marked-up OpenSearch-tuned equivalents). Both are low-risk if you size against real utilization, not peak assumptions.

Deep dive: Right-sizing steps and the EBS markup table → Cut OpenSearch Costs 15–20%: Right-Size Your Clusters


Decision framework: which storage should I use?

Your situation Use this Typical saving
Any GP2 volume GP3 ~20% + 10× IOPS on small volumes
io1/io2 under 16,000 sustained IOPS GP3 60–87%
RDS on io1/io2, sub-16K IOPS GP3 storage up to 60% on IOPS
Aurora, I/O > 25% of spend Aurora I/O-Optimized 30–40%
S3 objects with unknown/variable access Intelligent-Tiering up to 68%
Known archival S3 data Lifecycle → Glacier 80%+
Oversized OpenSearch/ES clusters Right-size + Graviton 15–20%
Genuinely need >16K IOPS or Multi-Attach io2 Block Express n/a (keep)

The rule of thumb: default to GP3, switch Aurora to I/O-Optimized if I/O is >25% of spend, tier S3, and reserve io1/io2 only for the rare workload that proves it needs them.


Doing it at scale

The reason these savings persist in almost every account isn’t ignorance — it’s that an enterprise has hundreds of accounts and thousands of volumes, and “migrate every GP2 to GP3” is nobody’s job. The changes themselves are individually trivial and low-risk; the operations problem is finding every candidate and applying the change safely across environments.

That’s exactly what CloudFix does: it continuously scans for these storage opportunities (plus Compute, Network, and Commitment discounts), shows the dollar impact, and applies each change with guardrails — safely, and only charging on realized savings. If you want to see the specific storage savings in your account before touching anything, run a free AWS savings assessment or try the AWS savings calculator.


FAQ

Does migrating GP2 to GP3 cause downtime? No. It’s a volume modification that completes within minutes, typically with no application disruption. You can do a single volume via the AWS CLI or thousands at once with an automation tool.

How do I know if my Aurora database should switch to I/O-Optimized? Check Cost Explorer for your Aurora cluster and compare the “I/O requests” usage cost to total Aurora spend. If I/O is more than ~25% of the total, I/O-Optimized will almost certainly save 30–40%.

Is S3 Intelligent-Tiering worth it for a small bucket? Usually not if the bucket has very few objects — the $0.0025/1,000-objects monitoring fee can outweigh the savings. It’s designed for buckets with many objects and mixed access patterns.

Will dropping io1/io2 hurt my database performance? Only if your workload genuinely sustains more than 16,000 IOPS or needs sub-millisecond latency guarantees. GP3 handles up to 16,000 IOPS, which covers the overwhelming majority of databases. Check actual IOPS utilization in CloudWatch before migrating.

How much can I actually save on AWS storage? It varies, but storage is commonly 20–30% of an AWS bill and the optimizations above typically recover 20–90% of the storage portion depending on what’s currently provisioned. Most accounts find storage is their single cleanest cost win.


Further reading