CloudFix Feature
AWS Storage Cost Optimization: The Complete Guide to EBS, Aurora & S3 (2026)
Storage is usually 20–30% of an AWS bill, and it's the part with the cleanest, lowest-risk savings on the platform.
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 | n/a | n/a | Up to 500 MiB/s | Big data, data warehouses |
| sc1 | HDD | $0.015 | n/a | n/a | 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/m__o(_G__P_2)t__o 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/_m__o__i__n__I__O__P__S__o__n__i__o_1 * *(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 safely, with guardrails, charging only 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
- GP2 vs GP3 on AWS: Save 20% and Get 3,000 IOPS
- GP3 vs io1/io2 on AWS: Cost, IOPS & When to Switch
- io1/io2 to GP3 on RDS: Cut IOPS Cost Up to 60%
- Aurora I/O-Optimized vs Standard: Which Is Cheaper in 2026?
- S3 Intelligent-Tiering: Does It Actually Save Money?
- Cut OpenSearch Costs 15–20%: Right-Size Your Clusters