The Request
It started with a simple Slack message from my manager:
"We've been running on **Aurora I/O Optimized* for a few months. Can we save money by converting back to Standard?"*
We had enabled I/O Optimized previously because the promise of "Free IOPS" sounded perfect for our high-traffic workloads. But without recent validation, we were flying blind.
This is the story of how I validated the costs, the "CloudWatch Trap" I fell into, and why we ultimately decided to revert to Standard—saving the company up to 26% on our database bill.
The Difference: It’s a Billing Flag, Not Hardware
My first step was checking if reverting would hurt performance. I dug into the AWS Documentation and confirmed that switching between Standard and I/O Optimized does not change the underlying hardware. It is purely a billing configuration.
Here is the trade-off (based on eu-west-1 pricing):
| Component | Standard Model | I/O Optimized Model (Our State) |
|---|---|---|
| Compute (ACUs) | ~$0.14 / hr | ~$0.19 / hr |
| Storage | ~$0.11 / GB | ~$0.25 / GB |
| I/O Requests | ~$0.22 / Million | $0.00 |
The math seems simple: Were we actually consuming enough IOPS to justify the massive premium we were paying for Compute and Storage?
The "CloudWatch Trap"
To answer that question, I tried to write a Python script to pull metrics from CloudWatch. I calculated the ServerlessDatabaseCapacity (ACUs) using the "Average" statistic over 30 days.
- The Result: The calculations was not accurate
Why? Granularity.
Aurora Serverless scales second-by-second. If your database spikes to 60 ACUs for 30 seconds and then drops, the AWS billing engine captures that cost perfectly. CloudWatch, however, averages that spike into the surrounding timeframe (often 1-5 minutes), smoothing out the data.
This makes the usage look much lower (and cheaper) than it actually is.
Lesson Learned: Never use CloudWatch averages to calculate your total monthly bill. It is a monitoring tool, not an accounting tool.
The Solution: The "10-Day Snapshot" Method
Since I couldn't trust CloudWatch for the total ACU cost, and AWS Cost Explorer is limited to 14 days of granular resource data, I developed a hybrid approach: The 10-Day Snapshot.
The logic is simple: If we are losing money over a representative 10-day period, we are losing money over the month.
Step 1: The Source of Truth (Cost Explorer)
I used Cost Explorer to get the exact billed amount for Compute (ACUs) for a specific window (e.g., Dec 11 - Dec 20).
-
Dimension:
Resource - Filter:
-
Usage Type:
EU-Aurora:ServerlessV2IOOptimizedUsage (ACU-Hr)(Since we were currently Optimized) - Resource: Select the relational databse then selct the DB instances
- Result: Get the exact amount of the used I/O.
Step 2: The Variable Costs (CloudWatch)
Since Cost Explorer doesn't easily split out "Storage" vs. "I/O" quantity for a specific custom window, I used the CloudWatch Console to get the raw usage data for the exact same 10-day period.
Here is exactly how I got the numbers:
-
Navigate to Metrics:
- Go to CloudWatch > All metrics.
- Select AWS/RDS > DBClusterIdentifier.
- Search for your cluster ID (e.g.,
client-db-01).
-
Select the Metrics:
- Check
VolumeBytesUsed(for Storage). - Check
VolumeReadIOPS(for I/O). - Check
VolumeWriteIOPS(for I/O).
- Check
-
Set the Timeframe:
- Click the date picker in the top-right.
- Select Custom > Absolute.
- Choose the exact same 10-day window you used in Cost Explorer.
-
Configure the Calculations (Graphed Metrics Tab):
-
For Storage: Set the Statistic to Average.
-
Math: Add the expression
m1/1024/1024/1024to convert raw bytes into GB.
-
Math: Add the expression
-
For I/O: Set the Statistic to Sum.
-
Math: Add the expression
m2+m3to add Read and Write IOPS together for the Total IOPS.
-
Math: Add the expression
-
Important: Ensure the "Period" is set to 30 Days (or a custom value like
864000seconds) so that CloudWatch gives you one single number for the entire duration, rather than a line graph.
-
For Storage: Set the Statistic to Average.
Step 3: The Comparison
Now we have the exact numbers for Total I/O, the Storage, and consumed ACUs.
I put the numbers into a spreadsheet to compare our current costs vs. what we would pay if we switched to Standard.
Scenario A: I/O Optimized (Actual Cost)
-
ACU Cost:
(Amount of used ACUs Cost Explorer) * 0.19 -
Storage Cost:
Avg GB * $0.248 * (10/30) - IOPS Cost: $0
Scenario B: Standard (Projected Cost)
-
ACU Cost:
(Amount of used ACUs Cost Explorer) * 0.14 -
Storage Cost:
Avg GB * $0.11 * (10/30)(The cheaper storage rate) -
IOPS Cost:
(Total IOPS) / 1,000,000 * $0.22
The Verdict
The results were eye-opening. We were overpaying on every single cluster.
Conclusion
We immediately scheduled maintenance windows and converted all clusters back to Aurora Standard.
The validation proved that while "Optimized" sounds better, sometimes the "Standard" option is the true hero for your budget. If you are currently running on I/O Optimized, take a 10-day snapshot and check your storage costs—you might be surprised by what you find.



Top comments (0)