Aurora Serverless v2: When 'I/O Optimized' Actually Costs You More
Source: Dev.to
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 because the promise of “Free IOPS” sounded perfect for our high‑traffic workloads. Without recent validation, we were flying blind.
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.
Pricing Comparison (eu‑west‑1)
| 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 premium we were paying for compute and storage?
The CloudWatch Trap
I wrote a quick Python script (using boto3) to pull metrics from CloudWatch and calculate the ServerlessDatabaseCapacity (ACUs) using the “Average” statistic over 30 days.
# Example snippet – not the full script
import boto3
client = boto3.client('cloudwatch')
response = client.get_metric_statistics(
Namespace='AWS/RDS',
MetricName='ServerlessDatabaseCapacity',
Dimensions=[{'Name': 'DBClusterIdentifier', 'Value': 'my-cluster'}],
StartTime=datetime.utcnow() - timedelta(days=30),
EndTime=datetime.utcnow(),
Period=300,
Statistics=['Average']
)
Result: The calculation was inaccurate. Aurora Serverless scales second‑by‑second. If the database spikes to 60 ACUs for 30 seconds and then drops, the AWS billing engine captures that cost precisely. CloudWatch, however, averages the spike over the surrounding 1‑5 minute window, smoothing the data and making usage appear lower (and cheaper) than it actually is.
Lesson Learned: Never use CloudWatch averages for accounting. CloudWatch is a monitoring tool, not a billing tool.
Hybrid Approach: The 10‑Day Snapshot
Because CloudWatch averages were unreliable and AWS Cost Explorer only provides 14 days of granular data, I devised a “10‑Day Snapshot” method:
- Identify a representative 10‑day window (e.g., Dec 11 – Dec 20).
- Use Cost Explorer to get the exact billed amount for Compute (ACUs) for that window.
- Filter by Usage Type:
EU-Aurora:ServerlessV2IOOptimizedUsage (ACU‑Hr)(since we were on Optimized). - Select the specific DB cluster as the resource.
- Filter by Usage Type:
- Gather Storage and I/O data from CloudWatch for the same window.
Steps to Pull Storage & I/O from CloudWatch
- Navigate to Metrics →
AWS/RDS→DBClusterIdentifier. - Select the cluster (e.g.,
client-db-01). - Choose the metrics:
VolumeBytesUsed(Storage)VolumeReadIOPS(Read I/O)VolumeWriteIOPS(Write I/O)
- Set the timeframe to the exact 10‑day window (Custom → Absolute).
- Configure calculations:
- Storage: Statistic = Average; apply expression
m1/1024/1024/1024to convert bytes to GB. - I/O: Statistic = Sum; apply expression
m2 + m3to combine read and write IOPS.
- Storage: Statistic = Average; apply expression
- Period: Set to a single value covering the whole window (e.g.,
864000seconds ≈ 10 days) so CloudWatch returns one number instead of a line graph.
Now we have the exact numbers for total I/O, storage, and consumed ACUs for the 10‑day period.
Cost Scenarios
| Scenario | ACU Cost | Storage Cost | IOPS Cost |
|---|---|---|---|
| A – I/O Optimized (Actual) | ACU_amount × $0.19 | Avg_GB × $0.248 × (10/30) | $0 |
| B – Standard (Projected) | ACU_amount × $0.14 | Avg_GB × $0.11 × (10/30) | (Total_IOPS / 1,000,000) × $0.22 |
All calculations are based on the 10‑day snapshot; the (10/30) factor scales the monthly storage rate to the 10‑day window.
The Verdict
The results were eye‑opening: we were overpaying on every single cluster. 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.