Reserved Instances vs Savings Plans: Which to Buy When
You're Leaving 30-40% on the Table
If you're running production workloads on AWS at on-demand pricing, you're overpaying by 30-72% depending on the commitment type. I've seen companies burn through $100K+/month on EC2 alone without a single reservation or savings plan. The math is simple, but the decision of what to buy and when trips up even experienced FinOps practitioners.
Here's the raw pricing difference for an m6i.xlarge in us-east-1:
| Pricing Model | Hourly Rate | Monthly Cost | vs On-Demand |
|---|---|---|---|
| On-Demand | $0.192 | $140.16 | baseline |
| Compute Savings Plan (1yr, No Upfront) | $0.131 | $95.63 | -32% |
| Compute Savings Plan (3yr, All Upfront) | $0.077 | $56.21 | -60% |
| EC2 Instance Savings Plan (1yr, No Upfront) | $0.121 | $88.33 | -37% |
| Standard RI (1yr, No Upfront) | $0.121 | $88.33 | -37% |
| Standard RI (3yr, All Upfront) | $0.054 | $39.42 | -72% |
| Convertible RI (1yr, No Upfront) | $0.131 | $95.63 | -32% |
The savings range from 32% to 72%. The question isn't whether to commit — it's what kind of commitment to make.
Understanding the Three Options
Reserved Instances (RIs)
RIs are the original commitment vehicle. You commit to a specific instance type, in a specific region, for 1 or 3 years.
Standard RIs:
- Locked to instance family, size, OS, tenancy, and region
- Can change Availability Zone and scope (AZ vs Region)
- Can sell on the RI Marketplace if you no longer need them
- Highest discount (up to 72%)
Convertible RIs:
- Can exchange for different instance families, sizes, OS, or tenancy
- Cannot sell on the RI Marketplace
- Lower discount than Standard RIs (up to 66%)
Savings Plans
Savings Plans are the newer, more flexible option. You commit to a dollar amount of compute per hour, not a specific instance.
Compute Savings Plans:
- Apply across EC2, Fargate, and Lambda
- Any instance family, size, OS, tenancy, or region
- Maximum flexibility, moderate discount (up to 66%)
EC2 Instance Savings Plans:
- Locked to a specific instance family and region
- Flexible on size, OS, and tenancy within that family
- Higher discount than Compute SP, less than Standard RI
The Decision Framework
┌─────────────────────────────────┐
│ Is the workload stable for │
│ at least 12 months? │
└──────────┬──────────────────────┘
│
┌──── Yes ──┴─── No ────┐
│ │
▼ ▼
┌────────────────┐ Stay on On-Demand
│ Do you know the │ (or use Spot for
│ exact instance │ fault-tolerant
│ type long-term? │ workloads)
└───┬─────────┬──┘
│ │
Yes ───┘ └─── No
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Standard RI │ │ Will you change │
│ (max savings) │ │ instance families │
│ │ │ or regions? │
└──────────────────┘ └──┬────────────┬──┘
│ │
Yes ───┘ └─── No
│ │
▼ ▼
┌──────────────┐ ┌──────────────────┐
│ Compute │ │ EC2 Instance │
│ Savings Plan │ │ Savings Plan │
│ (max flex) │ │ (balanced) │
└──────────────┘ └──────────────────┘
Side-by-Side Comparison
| Feature | Standard RI | Convertible RI | EC2 Instance SP | Compute SP |
|---|---|---|---|---|
| Max Discount (3yr, All Upfront) | 72% | 66% | 63% | 60% |
| Instance Family Flexibility | No | Yes (exchange) | No | Yes |
| Region Flexibility | No | No | No | Yes |
| Size Flexibility | Yes (within family) | Yes (via exchange) | Yes | Yes |
| OS Flexibility | No | Yes (via exchange) | Yes | Yes |
| Applies to Fargate | No | No | No | Yes |
| Applies to Lambda | No | No | No | Yes |
| Marketplace Resale | Yes | No | No | No |
| Payment Options | All/Partial/No Upfront | All/Partial/No Upfront | All/Partial/No Upfront | All/Partial/No Upfront |
Real Scenario: Choosing the Right Commitment
Let's walk through a real decision for a company spending $45,000/month on EC2.
Current On-Demand Breakdown
| Instance Type | Count | Region | Monthly Cost | Stable? |
|---|---|---|---|---|
| m6i.2xlarge | 12 | us-east-1 | $8,410 | Yes — core API |
| r6i.xlarge | 8 | us-east-1 | $4,858 | Yes — databases |
| c6i.xlarge | 20 | us-east-1 | $8,760 | Yes — batch processing |
| m6i.xlarge | 6 | eu-west-1 | $5,256 | Yes — EU API |
| t3.medium | 15 | us-east-1 | $1,825 | Somewhat — dev/staging |
| Various (spot + burst) | — | Multiple | $15,891 | No — ephemeral |
| Total | $45,000 |
Recommended Purchase Strategy
| Workload | Commitment Type | Term | Payment | Monthly Savings |
|---|---|---|---|---|
| m6i.2xlarge (12x, us-east-1) | Standard RI | 3yr, All Upfront | $42,336 upfront | $5,043/mo (60%) |
| r6i.xlarge (8x, us-east-1) | Standard RI | 3yr, All Upfront | $18,432 upfront | $2,914/mo (60%) |
| c6i.xlarge (20x, us-east-1) | EC2 Instance SP | 1yr, No Upfront | $0 upfront | $3,241/mo (37%) |
| m6i.xlarge (6x, eu-west-1) | EC2 Instance SP | 1yr, No Upfront | $0 upfront | $1,945/mo (37%) |
| t3.medium (dev/staging) | Compute SP | 1yr, No Upfront | $0 upfront | $584/mo (32%) |
| Spot/burst workloads | None | — | — | $0 |
| Totals | $60,768 upfront | $13,727/mo |
Annual savings: $164,724. The upfront payment of $60,768 pays for itself in 4.4 months.
Why These Choices?
- Core API (m6i.2xlarge): Standard RI because we know these will run for 3+ years on the same instance type. Maximum savings.
- Databases (r6i.xlarge): Same reasoning. Database instances rarely change family.
- Batch processing (c6i.xlarge): EC2 Instance SP because we might resize within the c6i family, and 1-year term gives us flexibility to reassess.
- EU API (m6i.xlarge): EC2 Instance SP for size flexibility.
- Dev/staging (t3.medium): Compute SP because these workloads shift between instance types frequently.
- Spot/burst: No commitment. These are ephemeral by nature.
Break-Even Analysis
Before committing, always calculate the break-even point — the minimum utilization needed to save money vs on-demand.
# break_even_calculator.py
def break_even_months(
on_demand_monthly: float,
commitment_monthly: float,
upfront_cost: float,
term_months: int
) -> float:
"""Calculate months until commitment breaks even vs on-demand."""
monthly_savings = on_demand_monthly - commitment_monthly
if monthly_savings <= 0:
return float('inf') # Never breaks even
break_even = upfront_cost / monthly_savings
return round(break_even, 1)
# Example: m6i.2xlarge Standard RI (3yr, All Upfront)
on_demand = 8410 # monthly
ri_effective = 3367 # monthly effective cost (upfront amortized)
upfront = 42336
months = break_even_months(on_demand, ri_effective, upfront, 36)
print(f"Break-even: {months} months")
# Output: Break-even: 8.4 months
# You save money for the remaining 27.6 months of the term
Break-Even by Commitment Type
| Commitment Type | Upfront | Monthly Effective | Break-Even | Risk |
|---|---|---|---|---|
| Standard RI (3yr, All Upfront) | $42,336 | $1,176/mo | 8.4 months | High — locked in |
| Standard RI (1yr, No Upfront) | $0 | $5,519/mo | 0 months | Medium — locked type |
| Compute SP (1yr, No Upfront) | $0 | $5,717/mo | 0 months | Low — fully flexible |
| Compute SP (3yr, All Upfront) | $28,944 | $804/mo | 3.8 months | Medium — long term |
No Upfront commitments have zero break-even time — you save from day one. The trade-off is a smaller discount.
Stacking Strategy: Layer Your Commitments
The optimal approach isn't picking one type. It's layering commitments from most to least specific:
Layer 1: Standard RIs (highest savings, lowest flexibility)
└── Cover your rock-solid, never-changing baseline workloads
└── ~30% of your compute spend
Layer 2: EC2 Instance Savings Plans (balanced)
└── Cover workloads stable in family/region but may resize
└── ~25% of your compute spend
Layer 3: Compute Savings Plans (most flexible)
└── Cover the rest of your predictable spend
└── ~20% of your compute spend
Layer 4: On-Demand + Spot (no commitment)
└── Variable, burst, experimental workloads
└── ~25% of your compute spend
Coverage Monitoring
# Check current RI utilization
aws ce get-reservation-utilization \
--time-period Start=2026-03-01,End=2026-03-22 \
--granularity MONTHLY \
--query 'UtilizationsByTime[0].Total.{
UtilizationPercentage: UtilizationPercentage,
PurchasedHours: PurchasedHours,
UsedHours: TotalActualHours
}'
# Check Savings Plans utilization
aws ce get-savings-plans-utilization \
--time-period Start=2026-03-01,End=2026-03-22 \
--granularity MONTHLY \
--query 'SavingsPlansUtilizationsByTime[0].Utilization.{
UtilizationPercentage: UtilizationPercentage,
UsedCommitment: UsedCommitment,
TotalCommitment: TotalCommitment
}'
# Get purchase recommendations from AWS
aws ce get-savings-plans-purchase-recommendation \
--savings-plans-type COMPUTE_SP \
--term-in-years ONE_YEAR \
--payment-option NO_UPFRONT \
--lookback-period-in-days SIXTY_DAYS \
--query 'SavingsPlansPurchaseRecommendation.SavingsPlansPurchaseRecommendationDetails[0].{
HourlyCommitment: HourlyCommitmentToPurchase,
EstimatedMonthlySavings: EstimatedMonthlySavingsAmount,
EstimatedSavingsPercentage: EstimatedSavingsPercentage
}'
Common Mistakes
Mistake 1: Buying 3-year All Upfront commitments for everything. Yes, the discount is highest, but you lose all flexibility. Start with 1-year No Upfront to learn your usage patterns.
Mistake 2: Over-committing. Never commit to more than 70-80% of your baseline. Leave room for optimization, migration, and natural traffic changes.
Mistake 3: Ignoring utilization tracking. Buy an RI and forget about it — then decommission the workload 6 months later. Now you're paying for idle commitments. Set up monthly utilization reviews.
Mistake 4: Not using AWS Cost Explorer recommendations. AWS analyzes your actual usage and suggests optimal purchases. Their recommendations are surprisingly good — start there.
Mistake 5: Waiting for the "perfect" time to buy. Every month you wait is a month of on-demand pricing. Even a conservative Compute Savings Plan with 1-year No Upfront saves 30%+ from day one with zero upfront cost and full flexibility.
Quick Decision Cheat Sheet
| Your Situation | Buy This | Why |
|---|---|---|
| Running same EC2 types for 3+ years | Standard RI (3yr) | Maximum savings, 60-72% off |
| Stable family, might resize | EC2 Instance SP (1yr) | Size flexibility, 37% off |
| Multi-service, multi-region | Compute SP (1yr) | Total flexibility, 30-32% off |
| First time buying commitments | Compute SP (1yr, No Upfront) | Zero risk, 30% savings, learn patterns |
| Using Fargate or Lambda heavily | Compute SP | Only option that covers these |
| Shutting down in < 12 months | Nothing — use On-Demand | Don't commit to what you won't use |
Start with Compute Savings Plans to cover your floor. Add EC2 Instance Savings Plans for your most stable workloads. Use Standard RIs only when you're certain the instance family won't change. Review coverage monthly and adjust quarterly.
Related Articles
Related Articles
The Complete AWS Cost Optimization Playbook: Compute, Storage, Networking, and Reserved Capacity
A data-driven playbook for cutting AWS costs across compute, storage, networking, and reserved capacity with real numbers and actions.
AWS EC2 Right-Sizing: Stop Overpaying for Compute
Find and fix oversized EC2 instances with this practical right-sizing guide. Save 30-50% on AWS compute costs using CloudWatch metrics and tooling.
AWS Lambda Cost Optimization: Memory Tuning, Provisioned Concurrency, and ARM
Cut your AWS Lambda costs by 40-70% with memory right-sizing, ARM/Graviton migration, and smart provisioned concurrency strategies.