Reserved Instances vs Savings Plans: How to Choose
Reserved Instances vs Savings Plans for EC2: discount ranges, flexibility, RI Marketplace resale, coverage vs utilization, and how to size a commitment.
Every few months somebody asks us whether they should buy Reserved Instances or Savings Plans. The short answer for most EC2 fleets is Savings Plans. The longer answer is that the headline discounts are nearly identical, and the real decision is about how wrong you’re allowed to be about next year.
Both are the same deal underneath: you promise AWS a level of usage for one or three years and it charges you less. What differs is how narrowly the promise is written, whether you can get out of it, and whether it holds a server for you. Get those wrong and you’re paying for a three-year reservation on an instance family you left in month eight.
The four options side by side
Discount figures are AWS’s own “up to” numbers, quoted from the Reserved Instances and Savings Plans pages at the time of writing.
| Standard RI | Convertible RI | EC2 Instance Savings Plan | Compute Savings Plan | |
|---|---|---|---|---|
| Up to (vs On-Demand) | 72% | 66% | 72% | 66% |
| You commit to | An instance type, platform and tenancy in a Region (or one AZ) | Same, but exchangeable | A $/hour spend on one instance family in one Region | A $/hour spend on EC2, Fargate and Lambda, any Region |
| Change size | Yes, for regional Linux/Unix RIs | Yes, by exchange | Yes | Yes |
| Change family, OS, tenancy | No | Yes, by exchange | OS and tenancy yes, family no | Yes |
| Change Region | No | No | No | Yes |
| Reserves capacity | Only if zonal | Only if zonal | No | No |
| Can be sold | Yes, RI Marketplace | No | No | No |
All four come in 1-year and 3-year terms with All, Partial or No Upfront payment. “Up to” is the best case: 3 years, paid up front, on the most discounted instance types. A 1-year No Upfront commitment is a lot less dramatic, so price your actual instances before building a business case on 72%.
Reserved Instances, properly
Standard vs Convertible
A Standard RI can be modified: you can move it between AZs, change its scope, and change size within a family if it’s a regional Linux/Unix RI. You can’t change family or operating system. In exchange you get the deepest discount and the ability to sell it.
A Convertible RI can be exchanged for another Convertible RI with a different family, OS or tenancy, as often as you like, as long as the new one is worth the same or more. It stays in the same Region, and a pricier target means a true-up payment. You can never trade down, which hurts if your fleet shrinks.
Zonal vs regional
A zonal RI is tied to one Availability Zone. It’s the only kind that reserves capacity, and it gets no size flexibility at all.
A regional RI applies its discount to matching usage in any AZ in the Region and, for Linux/Unix with default tenancy, across sizes in the family using normalization factors. A large counts as 4 units, an xlarge as 8, a 2xlarge as 16, so one m5.2xlarge regional RI covers two m5.xlarge instances. Size flexibility doesn’t apply to Windows, RHEL or SUSE RIs, dedicated tenancy, or a handful of GPU and accelerator families.
If what you need is guaranteed capacity, an On-Demand Capacity Reservation plus a Savings Plan or regional RI is usually cleaner than a pile of zonal RIs.
Selling on the RI Marketplace
Resale is real but narrower than people assume. Per the seller documentation:
- Only Standard EC2 RIs can be sold. Not Convertible, not RDS or ElastiCache, not RIs bought with a volume discount.
- You must have held the RI for at least 30 days, AWS must have received any upfront payment, and at least a month must remain on the term.
- AWS keeps a 12% fee on the upfront price.
- Registration needs the root user, a tax interview and a bank account with a US address.
- There’s a lifetime cap on what an account can sell ($50,000 or 5,000 RIs per the current docs).
- Customers of Amazon Web Services India Private Limited can’t sell at all.
Buy as if you’ll hold every RI to the end of its term. Resale might get some of the money back, but it’s slow and capped.
Savings Plans, properly
Compute vs EC2 Instance
An EC2 Instance Savings Plan commits you to spend on one family in one Region, say m7i in us-east-1. Size, OS and tenancy within that family can change freely. Moving from m6i to m7g for Graviton is a family change, so it falls outside the plan.
A Compute Savings Plan doesn’t care about family, size, OS, tenancy or Region, and it also covers Fargate and Lambda. You give up a few points of discount for that. If there’s a Graviton migration, a container move or a Region change anywhere on your roadmap, Compute is the safer buy. (We cover the Graviton side in Graviton and EC2 rightsizing.)
Database and SageMaker AI Savings Plans also exist; same idea, different services.
How a plan is applied each hour
The application rules explain most “why is my utilization low” tickets:
- The commitment is per hour. An unused hour is gone; it doesn’t roll over.
- RIs apply first, then EC2 Instance Savings Plans, then Compute Savings Plans.
- Within a plan, AWS applies the commitment to the usage with the highest savings percentage first.
- In an organization, the buying account’s usage is covered first and other accounts only benefit if sharing is enabled.
Commitment dollars are not On-Demand dollars
This is the mistake we see most often. A Savings Plan commitment is measured at the discounted rate. If your mix averages, say, 30% off, a $10/hour commitment covers roughly $14.30 of On-Demand usage. Take a $14.30/hour On-Demand baseline and commit $14.30/hour, and you’ve overbought by about 43%.
Savings Plans can’t be sold, exchanged or cancelled. The one escape hatch is a return: a plan with an hourly commitment of $100 or less can be returned within seven days of purchase, provided it’s still the same calendar month and you haven’t hit the return limit. That’s for typos, not for a change of heart in March.
Coverage and utilization
Two numbers tell you whether commitments are healthy, and they pull in opposite directions.
- Utilization is how much of what you bought actually got used. For a Savings Plan it’s commitment used over commitment purchased; for RIs it’s reserved hours (or normalized units) used. You want this close to 100%.
- Coverage is how much of your eligible usage ran at a committed rate. You want this as high as you can defend, which is never 100%, because 100% coverage on a fleet that moves means utilization drops the first quiet week.
# Read-only. Each Cost Explorer API request is billed at $0.01
# Last calendar month (GNU date first, BSD/macOS date as the fallback)
START=$(date -u -d "$(date -u +%Y-%m-01) -1 month" +%F 2>/dev/null || date -u -v1d -v-1m +%F)
END=$(date -u +%Y-%m-01)
aws ce get-savings-plans-utilization --time-period Start="$START",End="$END"
aws ce get-savings-plans-coverage --time-period Start="$START",End="$END" --granularity MONTHLY
aws ce get-reservation-utilization --time-period Start="$START",End="$END"
aws ce get-reservation-coverage --time-period Start="$START",End="$END" \
--group-by Type=DIMENSION,Key=INSTANCE_TYPE
# What you own and when it ends
aws ec2 describe-reserved-instances --filters Name=state,Values=active \
--query 'ReservedInstances[].[InstanceType,InstanceCount,Scope,OfferingClass,End]' --output table
aws savingsplans describe-savings-plans --states active \
--query 'savingsPlans[].[savingsPlanType,commitment,paymentOption,end]' --output table
Sizing a commitment from the hourly baseline
Monthly averages hide the shape that matters. A fleet averaging $60/hour On-Demand might sit at $38 at 4 a.m. on Sunday. Commit to the average and you pay for the gap every quiet hour.
- Pull hourly spend. Cost Explorer’s hourly granularity is opt-in, costs $0.01 per 1,000 usage records a month, and reaches back 14 days. For longer history, use hourly Data Exports.
- Find the floor. Look at the lowest hours across weekends, holidays and deploy windows. A low percentile is fine if one maintenance hour skews the minimum.
- Subtract what’s leaving. Workloads moving to Spot, being shut down, or migrating families. The query below already leaves out usage that existing RIs and plans cover. If you measured total spend some other way, subtract that coverage here as well, but only once.
- Convert to commitment dollars. Multiply the On-Demand floor by one minus the discount for your mix (the Savings Plans pricing pages list rates per instance type).
- Buy in tranches. Commit part now, watch utilization for a month, then add. Staggered purchases also mean staggered expiries.
- Cross-check. Cost Explorer’s recommendations and the Savings Plans purchase analyzer model a commitment against past usage. They don’t know your roadmap, so treat them as a second opinion.
# Read-only. The five lowest hours of On-Demand EC2 compute spend.
# Needs hourly granularity enabled in Cost Explorer preferences. Hourly data
# reaches back 14 days and the most recent hours are still incomplete, so the
# window runs from 13 days ago to 2 days ago.
# (GNU date first, BSD/macOS date as the fallback)
START=$(date -u -d '-13 days' +%FT00:00:00Z 2>/dev/null || date -u -v-13d +%FT00:00:00Z)
END=$(date -u -d '-2 days' +%FT00:00:00Z 2>/dev/null || date -u -v-2d +%FT00:00:00Z)
aws ce get-cost-and-usage \
--time-period Start="$START",End="$END" \
--granularity HOURLY --metrics UnblendedCost \
--filter '{"And":[{"Dimensions":{"Key":"SERVICE","Values":["Amazon Elastic Compute Cloud - Compute"]}},{"Dimensions":{"Key":"PURCHASE_TYPE","Values":["On Demand Instances"]}}]}' \
--query 'ResultsByTime[].Total.UnblendedCost.Amount' --output text \
| tr '\t' '\n' | sort -n | head -5
The On Demand Instances filter shows On-Demand spend that existing Reserved Instances and Savings Plans didn’t cover. That makes the result your uncovered floor, which is what a new commitment should be sized against, so don’t subtract existing commitments from it again.
An illustration with made-up round numbers: the floor is $40/hour On-Demand, $6 of that is Windows boxes being retired next quarter, so $34 is durable. If your mix gets about 28% off on a 1-year Compute plan, the full commitment is about $24.50/hour. Buy $18 now and decide on the rest after a month of data.
Layering, and where RIs still fit
Because RIs and EC2 Instance plans apply first, you can stack:
- Bottom layer: an EC2 Instance Savings Plan (or Standard RI) for the dull, stable family you’re confident won’t change.
- Middle layer: a Compute Savings Plan for the rest of the baseline, so it follows you through migrations.
- Top: On-Demand for daily peaks, and Spot for anything that tolerates interruption (our Spot guide covers that).
- Capacity: zonal RIs or Capacity Reservations only where running out of a type in one AZ would hurt.
RIs still make sense where you need a zonal capacity guarantee or want something you could resell.
Mistakes we keep seeing
- Sizing from the monthly average instead of the hourly floor.
- Committing On-Demand dollars as plan dollars.
- An EC2 Instance plan or Standard RI on a family you’re about to leave.
- Three years, all upfront, on a workload with a known end date.
- Buying in a member account with sharing disabled.
- Letting a big block expire on one day, so coverage falls off a cliff. Queue replacements ahead of expiry.
- Committing before rightsizing. You lock in the waste at a discount.
A decision checklist
- Have you rightsized and removed idle instances first?
- What’s your hourly floor over the longest hourly window you have, net of anything leaving?
- Any family, architecture or Region changes in the next 12 to 36 months? If yes, Compute Savings Plan.
- Need guaranteed capacity in one AZ? Capacity Reservation plus a plan, or a zonal RI.
- Is the family genuinely fixed for the term? Then an EC2 Instance plan or Standard RI earns the extra discount.
- Is a 3-year term defensible if the product changes?
- Will you buy in tranches, and who checks utilization and coverage monthly?
FAQ
Are Savings Plans better than Reserved Instances?
For most EC2 fleets, yes. The top discounts match, and Compute Savings Plans follow your usage across families, Regions, Fargate and Lambda. RIs win where you need zonal capacity or resale.
Can I sell a Savings Plan I no longer need?
No. Savings Plans can’t be sold or exchanged. The only exit is a return within seven days, in the same calendar month, for plans of $100/hour or less.
What is the difference between Compute and EC2 Instance Savings Plans?
EC2 Instance plans lock you to one instance family in one Region for up to 72% off. Compute plans work across families, Regions, Fargate and Lambda for up to 66% off.
Do Savings Plans reserve EC2 capacity?
No. Use On-Demand Capacity Reservations, which Savings Plans and regional RIs can discount, or zonal RIs.
What happens if I don’t use my full Savings Plan commitment?
You pay for the full hourly commitment anyway. Unused commitment in an hour is lost, which is why sizing to the hourly floor matters.
If you’re starting from zero
Turn on hourly granularity in Cost Explorer today. In two weeks you’ll have enough hours to run the floor query, and the utilization and coverage commands will tell you how the commitments you already own are doing. Size the first tranche from those numbers and use the recommendation screen as a cross-check. For discounts that don’t need an EC2 commitment at all, read AWS billing discounts you probably missed.
