RDS Reserved Instances: the basics
Why your database spend needs its own commitment strategy
A Reserved DB Instance (RDS RI) is a billing commitment, not a resource you launch. You promise AWS that you'll run a particular database shape — a specific engine, instance family, size, region, and Multi-AZ choice — for one or three years, and in exchange AWS discounts the hourly rate by up to roughly 60% versus On-Demand. Nothing about the running database changes; the discount is applied behind the scenes against any matching instance you happen to be running.
The reason RDS gets its own lesson is that it falls outside Savings Plans entirely. Compute Savings Plans and EC2 Instance Savings Plans cover EC2, Fargate, and Lambda — they do not cover RDS, ElastiCache, Redshift, OpenSearch, or any other managed-database compute. For RDS, the Reserved Instance is the only commitment lever you have. If your database tier is a meaningful slice of the bill and it's all running On-Demand, you're leaving the single largest structured discount on the table.
RDS RIs come in just three payment shapes — No Upfront, Partial Upfront, and All Upfront — and unlike EC2 there are no convertible RIs for RDS. Every RDS RI is a standard RI: you cannot exchange it for a different engine or family later. That rigidity is the whole game. Commit to the right shape and it's free money; commit to the wrong one and you've locked yourself into paying for a database you may not be running in eighteen months.
In this lesson you'll learn why RDS sits outside Savings Plans and needs its own Reserved Instance strategy, how RDS RIs are scoped (engine, instance family and size, region, Multi-AZ), where size-flexibility applies and where it doesn't, and the sequence that protects you — right-size and consolidate engines first, then commit. You'll see the AWS CLI calls that surface a purchase recommendation and that list what you already own, and the traps that strand a reservation: migrating engines, moving to Graviton, or adopting Aurora I/O-Optimized after you've committed to the old shape.
The reservation that outlived the database
RDS Reserved Instances offer size flexibility within a family and engine — a reservation for a db.r5.large can apply to a db.r5.xlarge (counting as two) or two db.r5.large instances, using normalized units. But that flexibility evaporates the moment you cross a family boundary. A team committed three years to a fleet of x86 db.r5 PostgreSQL instances, then migrated to Graviton db.r6g six months later for the better price-performance. The r6g instances ran On-Demand at full price while the r5 reservation kept billing against nothing — they paid for both. The Graviton migration that was supposed to save 10% cost them double until the original reservation finally expired two and a half years later.
Buying RDS reservations in action
Marco runs the platform team at a B2B SaaS company. The FinOps dashboard shows $38k of monthly RDS spend, almost entirely On-Demand, across a PostgreSQL fleet that's been stable for over a year. The Compute Savings Plan the company bought last quarter covers their EKS nodes beautifully — and does nothing for the databases.
Before committing a dollar, Marco does the unglamorous work first. He right-sizes two over-provisioned db.r5.4xlarge instances down to db.r5.2xlarge, consolidates a stray MySQL test database that nobody owned, and confirms the remaining fleet is genuinely steady-state — these databases will still be running this shape in a year. Only then does he pull the purchase recommendation.
Cost Explorer recommends a three-year Partial Upfront reservation covering the baseline of the db.r5 PostgreSQL fleet, projecting about 58% savings — roughly $18k a month. Marco buys to cover ~85% of the steady baseline, deliberately leaving the top of the curve On-Demand so a future right-size or Graviton move doesn't strand a reservation. He sets a calendar reminder for month 30 to plan the renewal.
First, ask Cost Explorer what it recommends buying for RDS. Scope it explicitly to the RDS service so you don't get EC2 noise.
The recommendation is scoped to one exact shape — that exact shape is what you're locking in for three years.
Now list what you already own, so you don't double-buy and can see what's expiring soon.
Listing active reservations exposes both double-buy risk and the stranded db.r5.4xlarge nobody runs anymore.
RDS reservations under the hooddeep dive
An RDS Reserved Instance is matched against your running databases by five attributes: AWS region, database engine (MySQL, PostgreSQL, MariaDB, Oracle, SQL Server, or Aurora MySQL/PostgreSQL), instance family and size (db.r5.2xlarge), and deployment option (Single-AZ vs Multi-AZ). All five must line up for the discount to apply to a given instance-hour. There is no convertible RI for RDS — every reservation is a standard RI, so once bought you cannot exchange the engine, family, or region. Your only post-purchase flexibility is within size, and only for some engines.
Size flexibility uses normalized units, the same mechanism as EC2 RIs. Within a single engine and family in one region, a reservation is measured in units proportional to size — a db.r5.large is 4 units, a db.r5.xlarge is 8, a db.r5.2xlarge is 16. A reservation for one db.r5.2xlarge can therefore cover two db.r5.xlarge or four db.r5.large, or partially cover a db.r5.4xlarge. Critically, this flexibility applies to the open-source-style engines (MySQL, PostgreSQL, MariaDB, and Aurora) for Single-AZ but is restricted for the license-included commercial engines (Oracle, SQL Server) — and it never spans families: a db.r5 reservation will not cover a db.m5, a db.r6g, or a db.r6i instance.
This is exactly why right-sizing and engine consolidation must come before the commitment. If you commit to db.r5 x86 and later move to Graviton db.r6g for its ~20% better price-performance, the r6g instances run On-Demand while the r5 reservation bills against thin air — you pay twice until it expires. The same trap applies to Aurora I/O-Optimized: switching an Aurora cluster from Standard to I/O-Optimized changes the instance-hour rate and pricing dimension, and a reservation bought against the Standard configuration may not apply cleanly. Sequence the architecture decisions first; buy the reservation against the shape you'll still be running in three years.
# Inspect the size-flexibility offering details before buying, so you know which
# instances the reservation can flex across.
aws rds describe-reserved-db-instances-offerings \
--product-description postgresql \
--db-instance-class db.r5.2xlarge \
--multi-az \
--offering-type "Partial Upfront" \
--duration 94608000 \
--query 'ReservedDBInstancesOfferings[0].{Id:ReservedDBInstancesOfferingId,Fixed:FixedPrice,Recurring:RecurringCharges,Flex:NormalizationSizeFactor}'
# Purchase against the chosen offering ID (this is the irreversible step).
aws rds purchase-reserved-db-instances-offering \
--reserved-db-instances-offering-id 248e7b75-1234-4abc-9def-0123456789ab \
--db-instance-count 6 \
--reserved-db-instance-id rds-ri-pg-r5-2xl-2026 What is the impact of leaving RDS uncommitted?
The direct impact is paying full On-Demand rates on one of your most stable, highest-volume cost categories. A db.r5.2xlarge Multi-AZ PostgreSQL instance runs roughly $1,400/month On-Demand; a three-year Partial Upfront reservation drops the effective rate by around 55–60%, to roughly $600/month. Across a six-instance baseline that's ~$18k a month — well over $200k a year — of discount that exists, is offered by AWS, and is simply not being claimed because no one owns the database commitment decision.
The second-order impact is the asymmetry with Savings Plans. Teams that have invested in Compute Savings Plans often believe their commitment coverage is healthy because the EC2 number looks great — but the database tier sits entirely outside that program and is invisible on the Savings Plan dashboard. The result is a blind spot: a large, committable, stable cost running at sticker price while everyone congratulates themselves on compute coverage. RDS coverage has to be tracked on its own meter or it disappears.
Then there's the stranding risk, which runs the opposite direction. Because RDS RIs are standard-only and non-convertible, an over-eager or premature commitment is expensive. Commit before right-sizing and you lock in the oversized shape. Commit to x86 and then migrate to Graviton (db.r6g), or flip an Aurora cluster to I/O-Optimized, and the reservation bills against nothing while the new instances pay On-Demand — you pay twice for the remaining term. The discount and the trap are two sides of the same rigidity.
Finally, this category is a maturity signal. An organisation that covers EC2 with Savings Plans but leaves RDS, ElastiCache, and Redshift uncommitted has a commitment program that stops at the easy, well-marketed instrument and doesn't reach the rest. The databases are usually the most predictable spend in the whole estate — if they're uncommitted, the commitment strategy isn't finished, it's just started.
How do you commit to RDS reservations safely?
Buying RDS reservations is a four-step sequence, and the order is the whole point: clean up the fleet, commit only to the stable baseline, choose the payment option deliberately, and review coverage and utilisation every month.
1. Right-size and consolidate engines BEFORE you commit
Reservations lock in a shape, so fix the shape first. Right-size over-provisioned instances down, consolidate stray engines (kill the one-off MySQL test DB nobody owns), and resolve any planned migrations — including x86-to-Graviton (db.r5 → db.r6g) and Aurora Standard-to-I/O-Optimized — before purchasing. A reservation bought against a shape you're about to abandon is stranded waste for the full term, and there's no convertible escape hatch for RDS.
2. Commit to the stable baseline, not the peak
Look at the trailing 60–90 days and find the floor — the database capacity that is always running. Commit to roughly 80–90% of that steady baseline and leave the variable top of the curve On-Demand. This deliberately under-covers so that a future right-size or migration doesn't strand a reservation. It's better to leave a little discount uncaptured than to buy a reservation you might not be able to use.
3. Choose the payment option as a cash decision
No Upfront, Partial Upfront, and All Upfront trade cash-now for discount-depth — All Upfront is deepest, No Upfront shallowest. There are no convertible RDS RIs, so term length (1 vs 3 years) is the other lever: 3-year deepens the discount but extends the lock-in. Match the term and payment to how confident you are the shape will persist and to the business's cost of capital — this is finance's call, with an explicit payback number, not a console default.
4. Review coverage and utilisation on every FinOps cadence
Track two numbers monthly: coverage (share of RDS hours covered by a reservation; target 80–95% on stable fleets) and utilisation (share of reserved capacity actually consumed; must stay near 100%). Watch expirations 60–90 days out so renewals are deliberate, not lapses. If utilisation drops, a migration or right-size has stranded a reservation — investigate before buying anything new.
# Pull the RDS-specific purchase recommendation across payment options to compare.
for opt in NO_UPFRONT PARTIAL_UPFRONT ALL_UPFRONT; do
echo "== $opt =="
aws ce get-reservation-purchase-recommendation \
--service "Amazon Relational Database Service" \
--term-in-years THREE_YEARS \
--payment-option $opt \
--lookback-period-in-days SIXTY_DAYS \
--query 'Recommendations[0].RecommendationSummary.{Savings:TotalEstimatedMonthlySavingsAmount,Pct:TotalEstimatedMonthlySavingsPercentage}'
done
# Check coverage of what you already run, so you don't double-buy.
aws ce get-reservation-coverage \
--time-period Start=$(date -u -d '30 days ago' +%F),End=$(date -u +%F) \
--filter '{"Dimensions":{"Key":"SERVICE","Values":["Amazon Relational Database Service"]}}' \
--query 'Total.CoverageHours.CoverageHoursPercentage' Quick quiz
Question 1 of 5You have a stable PostgreSQL fleet on x86 db.r5.2xlarge instances, fully On-Demand, and the team is planning a migration to Graviton db.r6g next quarter for better price-performance. What's the right move on RDS reservations?
You scored
0 / 5
Keep learning
Dig deeper into RDS reservation mechanics, size flexibility, and how databases fit the broader commitment strategy.
- Amazon RDS Reserved Instances documentation Authoritative reference on scoping, payment options, size flexibility, and how reservations match running databases.
- Amazon RDS pricing Current On-Demand and Reserved Instance rates per engine, instance class, and deployment option — the numbers behind the savings math.
- AWS Cost Explorer reservation purchase recommendations How Cost Explorer generates RDS RI recommendations and reports coverage and utilisation.
- FinOps Foundation — Cloud Rate and Usage Optimization Where commitment-based discounts like Reserved Instances fit the broader FinOps lifecycle and operating model.
You've completed Purchase RDS Reserved Instances. You now know why RDS sits outside Savings Plans and needs its own commitment lever, how reservations are scoped by engine, family, size, region, and Multi-AZ, where size flexibility helps and where it stops, and the sequence that protects you — right-size and consolidate first, commit to the stable baseline second. The next time the bill shows a large, uncommitted database fleet, you'll have a defensible path from On-Demand to a sound multi-year commitment without stranding a dollar.
Back to the library