# Reserved, Savings Plans, or nothing: when a one-year commitment is actually worth it at small scale

AWS will give you up to 72 % off compute if you promise to keep paying for it for three years. The number is real and it's in every cost-optimisation checklist. What the checklist doesn't say is what fraction of *your* bill the promise can apply to, and for the architecture most small teams run in 2026, the honest answer is: almost none of it.

We [published our bill](/en/blog/aws-bill-of-a-three-person-startup) and said we pay on-demand for everything. This is the working behind that sentence, the four instruments, what each one can and can't cover, and the rule we use for when to stop saying no.

## The four instruments

| Instrument | Covers | Doesn't cover | Typical 1-year, no-upfront discount |
|---|---|---|---|
| **Compute Savings Plan** | EC2, Fargate, Lambda, any region, any instance family | App Runner, anything that isn't compute | ~20–30 % (Lambda ~17 %) |
| **EC2 Instance Savings Plan** | EC2 in one family in one region | Everything else | ~30–40 % |
| **RDS / Aurora Reserved Instances** | Provisioned RDS and Aurora instances, per class | Aurora Serverless v2 | ~30–40 % |
| **DynamoDB reserved capacity** | Provisioned read/write capacity units | On-demand mode | ~50 % |

Three things to notice before doing any arithmetic. Savings Plans are commitments to *spend*, in dollars per hour, not to specific resources, which makes them flexible within what they cover. Reserved Instances are commitments to specific instance classes, which makes them cheaper and more brittle. And the list of things they *don't* cover is where a serverless-leaning architecture lives.

## What our bill can actually be covered by

Take the bill line by line and ask which instrument applies:

| Line | Monthly | Coverable by | Discount available |
|---|---|---|---|
| App Runner | $190 | nothing | 0 |
| Aurora Serverless v2 | $130 | nothing (no reservations for Serverless v2) | 0 |
| NAT Gateway | $100 → [$66](/en/blog/nat-gateway-the-most-expensive-line-you-do-not-see) | nothing | 0 |
| CloudWatch | $95 | nothing | 0 |
| CloudFront + S3 | $55 | CloudFront security bundle, min $ commitment far above us | 0 |
| DynamoDB on-demand | $35 | only if switched to provisioned, then reserved | 0 as configured |
| Secrets Manager, KMS | $66 | nothing | 0 |
| Lambda | $15 | Compute Savings Plan | 17 % → $2.50 |
| CodeBuild | $15 | nothing | 0 |
| Everything else | $50 | nothing | 0 |
| **Total** | **~$750** | **$15 coverable** | **~$2.50 / month** |

Two dollars and fifty cents. For a twelve-month commitment. The instruments that promise 72 % apply to 2 % of the bill, because the four largest lines are App Runner, Serverless Aurora, NAT and CloudWatch, and not one of them is reservable. The architecture that made the platform cheap to operate also made it impossible to discount.

<div class="article-figure">
<svg viewBox="0 0 900 230" width="100%" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Stacked bar of the 750 dollar monthly bill showing which parts a commitment could apply to. App Runner 190, Aurora Serverless v2 130, NAT 66, CloudWatch 95, CloudFront and S3 55, DynamoDB on-demand 35, secrets and KMS 66, CodeBuild and the rest 65 are all uncoverable. Only Lambda at 15 dollars is coverable by a Compute Savings Plan, saving about 2.50 dollars. A note: 2 percent of the bill is reservable.">
<g font-family="Inter,system-ui,sans-serif" font-size="11">
<text x="20" y="24" fill="#f1f3ff" font-size="14" font-weight="700">Which part of a $750 bill a commitment can touch</text>
<rect x="20" y="50" width="218" height="36" fill="#2a3150"/><text x="129" y="73" text-anchor="middle" fill="#9aa3c7">App Runner $190</text>
<rect x="238" y="50" width="149" height="36" fill="#2a3150"/><text x="312" y="73" text-anchor="middle" fill="#9aa3c7">Aurora Sv2 $130</text>
<rect x="387" y="50" width="109" height="36" fill="#2a3150"/><text x="441" y="73" text-anchor="middle" fill="#9aa3c7">CloudWatch $95</text>
<rect x="496" y="50" width="76" height="36" fill="#2a3150"/><text x="534" y="73" text-anchor="middle" fill="#9aa3c7">NAT $66</text>
<rect x="572" y="50" width="76" height="36" fill="#2a3150"/><text x="610" y="73" text-anchor="middle" fill="#9aa3c7">KMS+SM $66</text>
<rect x="648" y="50" width="63" height="36" fill="#2a3150"/><text x="679" y="73" text-anchor="middle" fill="#9aa3c7">CF+S3 $55</text>
<rect x="711" y="50" width="40" height="36" fill="#2a3150"/><text x="731" y="73" text-anchor="middle" fill="#9aa3c7" font-size="9">DDB</text>
<rect x="751" y="50" width="75" height="36" fill="#2a3150"/><text x="788" y="73" text-anchor="middle" fill="#9aa3c7" font-size="9">rest $65</text>
<rect x="826" y="50" width="17" height="36" fill="#4fffb0"/><text x="834" y="102" text-anchor="middle" fill="#4fffb0" font-size="10">Lambda $15</text>
<text x="20" y="130" fill="#9aa3c7">grey: not reservable · green: Compute Savings Plan applies</text>
<text x="20" y="160" fill="#ff6b8a" font-size="12" font-weight="700">Coverable: 2 % of the bill. Saving at 17 %: about $2.50 a month, for a 12-month promise.</text>
<text x="20" y="190" fill="#9aa3c7">The four biggest lines are exactly the services that trade a discount for not having to size anything.</text>
<text x="20" y="212" fill="#9aa3c7">This is not an argument against those services. It's the reason the checklist item doesn't apply yet.</text>
</g>
</svg>
</div>

## The other cost of a commitment

Even where a discount applies, a commitment has a price that isn't on the invoice: it's a bet that the architecture won't change for a year. Ours is changing. App Runner may become Fargate for the service that keeps hitting the 120-second limit. Aurora Serverless v2 may become a provisioned instance [if the load flattens](/en/blog/aurora-serverless-v2-review). One of the Lambdas is likely to become a container. Each of those moves would make a reservation on the old thing worthless and a reservation on the new thing something we'd have wanted.

A Compute Savings Plan is the exception here, and it's why it's the only one we'd consider first: it follows the spend across EC2, Fargate and Lambda, so "the Lambda became a container" doesn't strand it. Reserved Instances don't have that property. An Aurora RI for `db.r6g.large` is an `r6g.large` for a year, and if you resize, you're paying for both.

## The rule we use

We'll commit when three things are true at once:

1. **The coverable spend is at least $500 a month.** Below that, the saving is under $100 a month and the annual conversation isn't worth an afternoon. For us that means either compute has moved to Fargate or EC2, or the database has gone provisioned.
2. **The shape has been stable for six months.** Not the bill, the shape: the same services, the same instance classes, no migration on the roadmap. Six months of stability is the evidence that twelve more is likelier than not.
3. **We cover the baseline, not the peak.** A Savings Plan commitment is dollars per hour, every hour. Set it at 60–70 % of the *lowest* steady hourly spend, so that on the quietest night of the year the commitment is still fully used. Everything above it stays on-demand. Under-committing wastes a little discount; over-committing pays for capacity that isn't there.

And always one year, no upfront, first. The three-year discount is larger and the three-year bet is on an architecture that, for a team our size, will not exist in three years.

<div class="article-figure">
<svg viewBox="0 0 900 220" width="100%" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Chart of hourly compute spend over a week with a daily cycle. The line oscillates between a low of about 1.20 dollars an hour at night and 3 dollars an hour at midday. A horizontal commitment line is drawn at 0.80 dollars an hour, about 65 percent of the nightly trough, labelled commit here. The area below it is fully discounted every hour; the area above it stays on-demand. A second dashed line at 2 dollars an hour, labelled do not commit here, shows a commitment that would be unused every night.">
<g font-family="Inter,system-ui,sans-serif" font-size="12">
<text x="20" y="24" fill="#f1f3ff" font-size="14" font-weight="700">Where to set a Savings Plan commitment</text>
<line x1="60" y1="190" x2="880" y2="190" stroke="#9aa3c7"/><line x1="60" y1="40" x2="60" y2="190" stroke="#9aa3c7"/>
<text x="54" y="194" text-anchor="end" fill="#9aa3c7" font-size="10">$0/h</text><text x="54" y="124" text-anchor="end" fill="#9aa3c7" font-size="10">$1.5/h</text><text x="54" y="54" text-anchor="end" fill="#9aa3c7" font-size="10">$3/h</text>
<path d="M60,140 C90,140 100,60 130,60 C160,60 170,140 200,140 C230,140 240,60 270,60 C300,60 310,140 340,140 C370,140 380,60 410,60 C440,60 450,140 480,140 C510,140 520,60 550,60 C580,60 590,140 620,140 C650,140 660,60 690,60 C720,60 730,140 760,140 C790,140 800,60 830,60 C850,60 860,100 880,120" fill="none" stroke="#7b8cff" stroke-width="2"/>
<rect x="60" y="154" width="820" height="36" fill="#4fffb0" opacity="0.15"/>
<line x1="60" y1="154" x2="880" y2="154" stroke="#4fffb0" stroke-width="2"/><text x="876" y="150" text-anchor="end" fill="#4fffb0" font-size="11" font-weight="700">commit here · $0.80/h · ~65 % of the trough · used every hour</text>
<line x1="60" y1="100" x2="880" y2="100" stroke="#ff6b8a" stroke-width="1.5" stroke-dasharray="5,4"/><text x="876" y="96" text-anchor="end" fill="#ff6b8a" font-size="11">not here · $2/h · unused every night, paid anyway</text>
<text x="470" y="210" text-anchor="middle" fill="#9aa3c7" font-size="10">one week · daily cycle · everything above the green line stays on-demand</text>
</g>
</svg>
</div>

## What we'd tell a team at $3,000 a month

The picture changes with scale, and it changes with architecture more than with scale. A team spending $3,000 a month on Fargate and a provisioned Aurora cluster can cover perhaps $2,000 of it and save $600 a month with two commitments made in an afternoon; that's a real number and they should do it. A team spending $3,000 a month on App Runner, Serverless v2, CloudWatch and NAT can cover a few hundred, and their afternoon is better spent on [the CloudWatch line](/en/blog/your-logs-should-not-know-which-cloud) or [the NAT count](/en/blog/nat-gateway-the-most-expensive-line-you-do-not-see), where the savings are larger and don't require a promise.

Look at what you're actually paying for before you look at the discount table. If the biggest lines aren't on it, the answer is nothing, for now, and that's fine.

If you'd like the line-by-line reservability check on your own bill, [we do it in an hour](/contact).
