Amazon Aurora Cost Optimization in 2026: I/O-Optimized, Serverless v2 Scale-to-Zero, and Database Savings Plans

Switch to I/O-Optimized when I/O tops 25% of spend, drop non-prod Serverless v2 to 0 ACUs, and layer 3-year RIs with Database Savings Plans. Real SQL, Terraform, and 2026 pricing to cut Amazon Aurora bills fast.

Aurora Cost Optimization Guide (2026)

Updated: August 13, 2026

To optimize Amazon Aurora costs in 2026, switch clusters to Aurora I/O-Optimized when I/O charges exceed 25% of the cluster's total spend, drop non-production Aurora Serverless v2 clusters to a minimum of 0 ACUs so they auto-pause, and cover steady-state provisioned instances with 3-year Reserved Instances (up to 66% off) or the newer Database Savings Plans (up to 35% off, and the only way to discount serverless). Everything else, storage class, backup retention, Global Database replication, is a distant second in dollars saved.

  • The break-even for Aurora I/O-Optimized is when your RDS:StorageIOUsage line item exceeds ~25% of the cluster's total spend. Cost Explorer, grouped by Usage Type, tells you in five minutes.
  • Aurora Serverless v2 now scales to 0 ACUs (GA since November 2024) on Aurora PostgreSQL 13.15+ / 14.12+ / 15.7+ / 16.3+ and Aurora MySQL 3.08+. Dev clusters drop from ~$60/month to under $5.
  • Database Savings Plans (December 2024) give up to 35% off Serverless v2 and up to 20% off provisioned, 1-year only, no upfront.
  • For 3-year commitments on provisioned instances, Reserved Instances still win at up to 66% savings.
  • Aurora backup storage is free up to 100% of your cluster size; the leak is orphaned manual snapshots after cluster deletion.
  • Global Database charges $0.20 per million replicated write I/Os even on I/O-Optimized. That's the one exception people forget.

What actually shows up on an Aurora bill

Before you optimize anything, look at what you're paying for. Every Aurora bill I've audited breaks down into six line items, and the ratio between them tells you which lever to pull first. In Cost Explorer, filter Service to "Amazon Relational Database Service" and group by Usage Type. Anything starting with Aurora: is Aurora; anything else is regular RDS.

Here are the SKUs you'll see, in rough order of how often they dominate the bill:

  • Aurora:ServerlessV2Usage or InstanceUsage:db.r6g.*: compute. Usually 50–70% of the total. This is what Reserved Instances, Savings Plans, right-sizing, Graviton migration, and Serverless v2 scale-to-zero all attack.
  • Aurora:StorageUsage: $0.10/GB-month on Standard, $0.225/GB-month on I/O-Optimized (us-east-1). Auto-scales in 10 GB increments; you're billed for consumption, not allocation. Typically 5–15% of the bill.
  • Aurora:StorageIOUsage: $0.20 per million I/O requests on Standard. Zero on I/O-Optimized. This is the line that decides which storage class you should be on.
  • Aurora:BackupUsage: $0.021/GB-month over your cluster size. Should be tiny unless retention is long or manual snapshots have piled up.
  • Aurora:CrossRegionIO: $0.20 per million replicated write I/Os for Global Database. This line item bites people who enable Global "just in case."
  • DataTransfer-Regional-Bytes: cross-AZ traffic between your app and the writer. Free if same-AZ; ~$0.01/GB otherwise (both directions).

Every optimization below is triggered by the ratio between these lines, not by any absolute number. Grab the last full month's export and I'll show you how to read it.

Aurora I/O-Optimized vs Standard: the 25% rule

Aurora I/O-Optimized is a storage configuration that eliminates per-I/O charges in exchange for a higher rate on both compute (~30% premium on ACU-hours and instance-hours) and storage ($0.225 vs $0.10 per GB-month). The trade is only worth it when your I/O bill is large enough to overwhelm the premium.

The heuristic AWS itself publishes is simple. If Aurora:StorageIOUsage is more than 25% of the cluster's total spend, switch to I/O-Optimized. Below that, Aurora Standard is cheaper. This is the same number the Aurora I/O-Optimized launch post gives, and it still holds in 2026.

Running the numbers on your own cluster

You don't need to guess. Pull the actual usage from Cost Explorer or the CUR. Here's a quick SQL query against a Cost and Usage Report loaded into Athena:

-- Aurora storage/IO ratio per cluster, last 30 days
SELECT
  resource_tags_aws_created_by                                AS creator,
  line_item_resource_id                                       AS cluster_arn,
  SUM(CASE WHEN line_item_usage_type LIKE '%StorageIOUsage%'
           THEN line_item_unblended_cost ELSE 0 END)          AS io_cost,
  SUM(CASE WHEN line_item_usage_type LIKE '%InstanceUsage%'
             OR line_item_usage_type LIKE '%ServerlessV2%'
           THEN line_item_unblended_cost ELSE 0 END)          AS compute_cost,
  SUM(line_item_unblended_cost)                               AS total_cost,
  ROUND(100.0 * SUM(CASE WHEN line_item_usage_type LIKE '%StorageIOUsage%'
                         THEN line_item_unblended_cost ELSE 0 END)
              / NULLIF(SUM(line_item_unblended_cost), 0), 1)  AS io_pct
FROM aws_billing.cur
WHERE product_product_family = 'Database Instance'
  AND line_item_product_code = 'AmazonRDS'
  AND line_item_usage_type LIKE '%Aurora%'
  AND line_item_usage_start_date >= current_date - interval '30' day
GROUP BY 1, 2
HAVING SUM(line_item_unblended_cost) > 50
ORDER BY io_pct DESC;

Any cluster with io_pct > 25 is a switch candidate. In practice, OLTP workloads with heavy write amplification (event ingestion, audit trails, workflow engines) often land at 40–60% and save 20–35% net after switching. Honestly, the first time I ran this on a customer account, three clusters jumped out immediately and paid for the whole engagement inside a month.

The one exception: Global Database write replication

I/O-Optimized does not waive the cross-region replicated write I/O charge for Aurora Global Database. That line still bills at $0.20 per million, regardless of storage class. If Global Database is a big chunk of your bill, budget for it separately (see the Global Database section below).

Aurora Serverless v2 and scale-to-zero

Aurora Serverless v2 bills on Aurora Capacity Units (ACUs) at $0.12/ACU-hour on Standard and $0.156/ACU-hour on I/O-Optimized. One ACU is roughly 2 GB of memory plus proportional CPU. Scaling happens per-second in 0.5 ACU increments, between a minimum and maximum you configure. Since October 2024, the ceiling is 256 ACUs (512 GiB), and since November 2024, the floor can be 0 ACUs.

Zero-ACU means the cluster auto-pauses after an inactivity window you set (5 minutes to 24 hours, keyed on the presence of active connections). While paused, you pay zero for compute and continue to pay for storage. It's the same model as Aurora Serverless v1's old auto-pause, but without v1's other limitations. The official scale-to-zero launch announcement lists the minimum engine versions: Aurora PostgreSQL 13.15+, 14.12+, 15.7+, 16.3+; Aurora MySQL 3.08+.

Enabling scale-to-zero the right way

The rule I use with my customers: set min=0 on dev, staging, CI, and internal-tool clusters; keep min ≥ 0.5 on anything a paying user hits. Cold resume takes 10–30 seconds. It's fine for a developer psql session, terrible for a checkout page.

Here's the Terraform snippet I ship as a module default for non-production clusters:

resource "aws_rds_cluster" "app_dev" {
  cluster_identifier      = "app-dev"
  engine                  = "aurora-postgresql"
  engine_version          = "16.4"                # scale-to-zero supported
  engine_mode             = "provisioned"         # required for Serverless v2
  storage_type            = "aurora-iopt1"        # I/O-Optimized; skip if I/O is low
  database_name           = "app"
  master_username         = "app_admin"
  manage_master_user_password = true

  # Serverless v2 scaling config
  serverlessv2_scaling_configuration {
    min_capacity             = 0     # auto-pause when idle
    max_capacity             = 4     # 8 GB / ~2 vCPU ceiling for dev
    seconds_until_auto_pause = 300   # 5 minutes idle -> pause
  }

  backup_retention_period = 1        # dev doesn't need 7 days
  skip_final_snapshot     = true
}

resource "aws_rds_cluster_instance" "app_dev_writer" {
  identifier         = "app-dev-writer"
  cluster_identifier = aws_rds_cluster.app_dev.id
  engine             = aws_rds_cluster.app_dev.engine
  instance_class     = "db.serverless"
}

With this config, a dev cluster that used to run 24/7 at min=0.5 (~$43/month in compute) drops to whatever the developers actually touch it. Usually $2–$8/month in compute plus ~$3 in storage. I've watched a fleet of 40 dev clusters go from $2,400/month to under $300 with this single change. That was a good Tuesday.

Production: pick your floor from the p50, not the p99

The floor ACU value on production Serverless v2 is where most teams overspend. If your baseline daytime traffic hovers at 2 ACUs and spikes briefly to 12, don't set min=8 "for headroom." That runs 24/7 whether you need it or not. Set min=1 or 2, let scaling handle spikes, and monitor ServerlessDatabaseCapacity in CloudWatch. Aggregating ACU usage over a week tells you the honest floor:

# Get p50 / p95 ACU usage over 7 days
aws cloudwatch get-metric-statistics \
  --namespace AWS/RDS \
  --metric-name ServerlessDatabaseCapacity \
  --dimensions Name=DBClusterIdentifier,Value=app-prod \
  --start-time  "$(date -u -v-7d +%Y-%m-%dT%H:%M:%SZ)" \
  --end-time    "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --period      3600 \
  --statistics  Average p50 p95 Maximum

Set the floor around the p50; let the max cover the p95. If p50 is 8 ACUs and it's flat all day, you're probably in provisioned-plus-RI territory instead. See the next section.

Reserved Instances vs Database Savings Plans

Prior to December 2024, Aurora had only Reserved Instances for commitment-based discounts, and they didn't apply to Serverless v2 at all. AWS fixed that with Database Savings Plans, which discount both provisioned and serverless usage across region, family, and engine. But they don't replace RIs. They overlap awkwardly, and the right answer usually uses both.

Dimension Aurora Reserved Instances Database Savings Plans
Max discount, 1-yearUp to 45%Up to 35% (serverless) / 20% (provisioned)
Max discount, 3-yearUp to 66%Not available (1-year only)
Payment optionsNo Upfront / Partial / All UpfrontNo Upfront only
Covers Aurora Serverless v2NoYes
Covers provisioned AuroraYesYes
Family/size flexibilitySame family (e.g., all r6g)Any family, any region, any engine
Cross-regionNo (region-locked)Yes
Can combine with RIs?n/aNo overlap on the same instance-hour

The decision tree that actually works

My default recommendation to teams running mixed Aurora fleets:

  1. Steady provisioned workloads you'd bet 3 years on (analytics warehouses, single-tenant SaaS databases, ERPs): cover 70–80% of the baseline with 3-year All Upfront RIs. That's the deepest available discount on Aurora, period.
  2. Serverless v2 workloads with a stable baseline (the ACU floor you set never drops below X for weeks at a time): buy a 1-year Database Savings Plan sized to that baseline. It's the only way to discount Serverless v2 hours.
  3. Provisioned workloads you're less confident about (new products, migrations still stabilizing, teams that may reorg): 1-year Savings Plan at 20%. You keep family and region flexibility, which matters when you're not sure what instance class you'll actually settle on.
  4. Anything spiky, seasonal, or genuinely elastic: leave on-demand. Discount only what's steady.

The general commitment strategy behind this (layer commitments so RIs cover the deep baseline, Savings Plans cover the middle band, and on-demand handles the spike) applies across AWS. If you want the broader mental model, see our writeup on cloud commitment discounts across AWS, Azure, and GCP. For picking coverage and utilization targets on the compute side, see Compute Savings Plans coverage and utilization strategy.

Aurora Global Database: the hidden replication tax

Aurora Global Database is beautiful engineering: sub-second cross-region replication, managed failover, unlimited secondary clusters. It's also the single easiest way to double your Aurora bill without noticing.

Costs stack in three places:

  1. Replicated write I/Os: $0.20 per million, matching your primary region's write I/O count, per secondary region. This applies on both Standard and I/O-Optimized. I/O-Optimized only waives regular in-region I/O.
  2. Secondary cluster compute and storage: you pay full price for the writer/reader instances (or ACUs) and full storage rate in each secondary region.
  3. Cross-region data transfer: replication traffic itself is bundled into the per-million charge, but application reads that go over a region boundary incur normal inter-region transfer rates (~$0.02/GB).

Say your primary in us-east-1 does 5 billion write I/Os per month with one secondary in eu-west-1. That's 5,000 × $0.20 = $1,000/month in replication charges alone, before compute or storage in the secondary. If you're only using Global for disaster recovery and rarely read from the secondary, ask whether cross-region snapshot copy on a schedule would meet your RPO for a fraction of the cost. I've moved two teams off Global Database this year for exactly that reason.

Backups, snapshots, and orphaned volumes

Aurora's backup pricing is generous: automated backup storage up to 100% of your cluster size is free. Beyond that, backup storage is $0.021/GB-month. For a well-scoped 200 GB cluster with 7-day retention, you're almost always inside the free tier.

Two things blow this up:

  • Long retention. Bumping retention from 7 to 35 days on a heavily-written cluster can 5× backup storage because Aurora keeps the change log for the full window. Compliance sometimes requires it; often nobody remembers who set 35 days or why. Audit annually.
  • Orphaned manual snapshots. When you delete an Aurora cluster, manual snapshots are not deleted. I've seen accounts with $600/month of snapshots from clusters deprecated three years ago. AWS Backup, or a scheduled Lambda that lists snapshots without a matching cluster, catches these.

Here's the one-liner I run in every audit:

aws rds describe-db-cluster-snapshots \
  --snapshot-type manual \
  --query 'DBClusterSnapshots[?SnapshotCreateTime<=`2024-01-01`].[DBClusterSnapshotIdentifier,DBClusterIdentifier,AllocatedStorage,SnapshotCreateTime]' \
  --output table

Anything from a source cluster that no longer exists is a candidate for deletion. Confirm with whoever owned the cluster first (there's usually one Slack message that reveals whether it was retained on purpose). For a broader sweep of forgotten AWS resources, see our guide on finding and eliminating zombie cloud resources.

Right-sizing and continuous monitoring

Aurora right-sizing is more forgiving than EC2 because storage and compute scale independently, but you still lose money running provisioned instances at 15% CPU. AWS Compute Optimizer covers Aurora provisioned clusters (Serverless v2 is exempt, since it's already self-scaling), and its recommendations are worth acting on if you have 14+ days of stable metrics. Our guide on AWS Compute Optimizer right-sizing walks through the workflow.

What to alert on

The four CloudWatch metrics worth alarming on for cost (not just performance):

  • CPUUtilization: alert if the 7-day average is below 20% (candidate for downsize or Serverless v2 migration).
  • ServerlessDatabaseCapacity: alert if daily p95 is consistently at your max ceiling (capacity is being throttled; raise max) or if daily p95 < 40% of max (waste).
  • VolumeReadIOPs plus VolumeWriteIOPs summed and multiplied by $0.20 per million: if the resulting monthly cost exceeds 25% of your cluster spend, you're on the wrong storage class.
  • DatabaseConnections: a Serverless v2 cluster that shows 0 connections for hours at a time but isn't scaling to zero probably has an idle listener holding a socket open (RDS Proxy, a monitoring agent, an orphaned worker). Fix the connection or accept it won't ever pause.

The engine choice matters too

Aurora on Graviton (r7g, r8g, and the Serverless v2 shared fleet) runs at the same ACU price but delivers ~20% better price/performance than r6i. If you're still on Intel-based Aurora instances (r5, m5, r6i) and haven't tested Graviton yet, it's the single easiest right-sizing move: same price, more headroom, lower ACU floor when you migrate to Serverless v2. Our Graviton migration guide covers the compatibility gotchas (there are basically none for Aurora since AWS manages the OS).

For the broader database cost picture across engines and clouds, our managed PostgreSQL cost comparison stacks Aurora against RDS, Cloud SQL, and Azure Flexible Server on real workloads.

Frequently Asked Questions

Does Aurora Serverless v2 actually scale to zero in 2026?

Yes. Since November 2024, setting minimum capacity to 0 ACUs causes Aurora Serverless v2 to auto-pause after an idle window you configure (5 minutes to 24 hours). Supported on Aurora PostgreSQL 13.15+, 14.12+, 15.7+, 16.3+ and Aurora MySQL 3.08+. Compute charges drop to zero; storage continues to bill.

Is Aurora I/O-Optimized worth it for my cluster?

Only if your I/O charges exceed roughly 25% of your total Aurora spend for that cluster. Below that, the higher compute and storage rates of I/O-Optimized outweigh the eliminated per-request I/O charges. Check Cost Explorer grouped by Usage Type. If StorageIOUsage is over a quarter of the cluster total, switch.

Can I use Reserved Instances with Aurora Serverless v2?

No. Reserved Instances only apply to provisioned Aurora instances. For Serverless v2 discounts, you need Database Savings Plans (introduced December 2024), which cover Serverless v2 at up to 35% off for a 1-year commitment.

What's the cheapest way to run an Aurora dev/test cluster?

Aurora Serverless v2 with min=0 and max=2–4 ACUs, on a supported engine version, and a 300-second auto-pause window. A typical dev cluster drops from ~$40–$60/month to $3–$8/month once developers stop touching it overnight and on weekends.

Do Aurora Global Database secondary regions get I/O-Optimized savings?

Partially. In-region I/O in the secondary is waived under I/O-Optimized, but the cross-region replicated write I/O charge ($0.20 per million) still applies on both storage classes. If Global Database is a large line item, that replication charge is the one to plan for.

How do I know if I'm over-provisioned on Serverless v2?

Pull the ServerlessDatabaseCapacity metric from CloudWatch over 7–14 days. If your daily p95 is consistently below 40% of your configured max ACU ceiling, lower the max. If your p50 sits well above your configured min, lower the min. The floor should track the honest baseline, not a headroom fantasy.

Pavel Dvorak
About the Author Pavel Dvorak

AWS solutions engineer with an unhealthy interest in Compute Savings Plans. Will run the numbers for you over coffee.