MercadoFresco has switched off what was surplus, deleted what nobody was using and put limits on what can grow. The bill sits at 1,749.60 USD a month and every line has an explanation. One lever remains unused, and it is the only one that reduces spend without changing absolutely anything in the architecture: everything that is running is paid for at on-demand price, that is, at the price charged to someone who could walk away tomorrow. And part of that consumption will still be there in a year's time with complete certainty.
This lesson is about turning that certainty into a discount. You will see the four purchase models with their discount, their commitment and their risk; Savings Plans in their three variants, with terms and payment options; how the dollar-per-hour commitment works, with a step-by-step numerical example; what each type covers — critical in an architecture like this one, mostly serverless; Reserved Instances for what Savings Plans cannot reach; how to identify the stable base against the elastic portion; MercadoFresco's concrete purchase plan with its savings; and the monitoring through coverage and utilisation, which are two different things and are constantly confused.
Cost warning. Savings Plans and Reserved Instances cost nothing in themselves: they are a different way of paying for what you already consume. The risk is not an unexpected charge, it is over-committing: a 3-year plan paid all upfront cannot be cancelled, refunded or reduced. What you buy, you pay for. The discount percentages in this lesson are indicative, they vary by region, service and date, and they must always be checked in the official calculator before buying. Fictitious data and identifiers.
Contents
- Why the commitment discount exists
- The four purchase models
- The three types of Savings Plans
- Terms and payment options
- How the dollar-per-hour commitment works
- A step-by-step numerical example
- What each plan covers and what it does not
- Reserved Instances: what Savings Plans cannot reach
- Standard versus convertible, scope and capacity reservation
- Spot, revisited from the cost angle
- Identifying the stable base against the elastic portion
- Automatic recommendations and why they are not decisions
- MercadoFresco's purchase plan
- Before and after
- Coverage and utilisation: two different things
- Monitoring and alarms
- What to do if the architecture changes
- Sharing commitments across accounts
- Expensive mistakes
- Common Mistakes and Tips
- Exercises
- Conclusion
Why the commitment discount exists
AWS's business logic is the same as that of any provider with physical infrastructure: data centres are built in advance. A server bought today has to be amortised over years, and that requires a forecast of demand.
A customer paying on-demand contributes no forecast: they can leave tomorrow. A customer who commits in writing to spending a specific amount over one or three years does contribute one, and AWS returns part of that value in the form of a discount.
Everything else follows from that, with no need to memorise tables:
- The longer the term, the bigger the discount: three years are worth more than one.
- The more you pay upfront, the bigger the discount: money today is worth more than money in a year's time.
- The less flexibility, the bigger the discount: committing to one specific instance family is worth more than committing to "compute in general".
- The risk shifts to the customer: if you stop using it, you pay for it anyway.
That last point is the one to keep in mind throughout the lesson. A commitment is a bet on the future, and like any bet it is sized by what you can lose, not by what you can win.
The four purchase models
| Model | Typical discount | Commitment | Flexibility | Risk | Interruptions |
|---|---|---|---|---|---|
| On-demand | 0 % | None | Total | None | No |
| Savings Plans | 20-66 % | 1 or 3 years, in USD/hour | High: you can change instance, region or service without losing it | You pay even if you do not use it | No |
| Reserved Instances | 20-72 % | 1 or 3 years, in specific instances | Low or medium depending on the type | You pay even if you do not use it; convertible ones can be exchanged | No |
| Spot | Up to 90 % | None | High | You can be interrupted with 2 min notice | Yes |
All four combine, and the combination is the norm in a mature architecture. The right mental order for deciding:
graph TD A["Does the workload tolerate<br/>interruptions?"] -->|Yes| SPOT["Spot<br/>up to -90 %"] A -->|No| B["Is consumption<br/>stable and predictable?"] B -->|No| OD["On-demand<br/>no commitment"] B -->|Yes| C["Is the service covered<br/>by Savings Plans?"] C -->|Yes: EC2, Fargate, Lambda| SP["Compute<br/>Savings Plan"] C -->|No: RDS, ElastiCache,<br/>Redshift, OpenSearch| RI["Reserved<br/>Instances"]
MercadoFresco has already been taking the first path since 10-02: the workers run on Fargate Spot because their work retries itself. What is missing is walking the other two.
The three types of Savings Plans
| Type | What it covers | Maximum discount | Flexibility |
|---|---|---|---|
| Compute Savings Plans | EC2, Fargate and Lambda, in any region, family, size, operating system and tenancy | Up to 66 % | Maximum: you move from EC2 to Fargate and it still applies |
| EC2 Instance Savings Plans | EC2 only, of one specific family in one specific region | Up to 72 % | Low: you can change size and operating system within that family |
| SageMaker Savings Plans | SageMaker usage | Up to 64 % | Medium: across SageMaker instances and components |
The comparison that matters for almost everybody is between the first two:
- The EC2 Instance one gives about 6-8 percentage points more discount, but it ties you to the
m6gfamily ineu-west-1. The day you want to move tom7g, to another region or to containers, the commitment stops being any use to you and you keep paying for it. - The Compute one gives slightly less and survives almost any architectural change. It still applies if you migrate from EC2 to Fargate, if you change region, if you move part of the work to Lambda.
For MercadoFresco there is no debate: the EC2 Instance Savings Plan is of no use whatsoever, because it has practically no EC2. Its compute lives in Fargate and Lambda, and both are only covered by the Compute Savings Plan. This is exactly the kind of detail that means automatic recommendations have to be read with judgement.
And a vocabulary warning that saves confusion: some commercial communications also mention a third product called database Savings Plans, but coverage for RDS, Aurora, ElastiCache or Redshift is bought with Reserved Instances, not with compute Savings Plans. Getting that wrong leads to buying a commitment that covers none of what you intended.
Terms and payment options
Two independent axes that combine into six options:
| Term | Payment | Approximate discount on Fargate | Initial outlay |
|---|---|---|---|
| 1 year | No upfront | ~20 % | 0 USD |
| 1 year | Partial (50 % upfront) | ~22 % | Half the year |
| 1 year | All upfront | ~24 % | The whole year |
| 3 years | No upfront | ~40 % | 0 USD |
| 3 years | Partial | ~46 % | Half of three years |
| 3 years | All upfront | ~52 % | Everything, in one go |
Two readings of this table, and both are important:
- The payment option contributes little. Between "no upfront" and "all upfront" over one year there are about 4 percentage points. For MercadoFresco, 4 points on a small commitment are a few dollars a month in exchange for tying up the entire annual amount. It is not worth it. For a company committing hundreds of thousands of dollars, those 4 points really are a lot of money, and the decision is a financial one: it depends on the opportunity cost of capital.
- The term contributes a great deal. Doubling the discount from 20 % to 40 % by going from one year to three is a real difference. And so is the risk: three years is longer than half the architectural decisions in this course have lasted.
The rule MercadoFresco adopts, and one that works for most small and medium companies: first commitment at 1 year with no upfront. You learn how it works, you check that the forecast was good, and when you renew it — with a year of real data — you can consider three years for whatever has proved to be stable.
How the dollar-per-hour commitment works
Here is the concept that gets misinterpreted most often. A Savings Plan does not buy instances: it buys an hourly spend at a reduced price.
When you take out a Compute Savings Plan of 0.17 USD/hour, what you are saying is:
"I commit to spending 0.17 USD every hour, for a year, on eligible compute. In exchange, that spend is billed at the Savings Plan rate instead of the on-demand rate."
How it works hour by hour:
- AWS looks at your eligible compute consumption in that hour and values it at the Savings Plan rate.
- It applies the commitment until it is exhausted, starting with the usage that has the highest discount percentage — it does this automatically to maximise your saving.
- Any usage above the commitment is billed at on-demand price.
- If consumption does not reach the commitment, the difference is paid anyway. That is the risk, and it is the only way to lose money with a Savings Plan.
Three practical consequences worth being clear about:
- The commitment is expressed in money, not in capacity. If AWS lowers prices, your commitment covers more machines.
- It is hourly, not monthly. There is no offsetting between hours: an hour with no consumption is not recovered by an hour of heavy consumption. That is why it is sized on the sustained minimum, not on the average.
- It does not reserve capacity. A Savings Plan does not guarantee that machines will be available; it only changes the price. To guarantee capacity you need zonal reservations or capacity blocks.
A step-by-step numerical example
Suppose a commitment of 0.17 USD/hour on a 1-year Compute Savings Plan, with a 20 % discount on Fargate. That means 1 USD of on-demand usage costs 0.80 USD at the plan rate, and therefore the 0.17 USD/h commitment covers 0.2125 USD/h of usage at on-demand price (0.17 ÷ 0.80).
Hour A: consumption exactly equal to the commitment.
Usage valued at on-demand price ......... 0.2125 USD Valued at Savings Plan rate ............. 0.1700 USD <- consumes the whole commitment Usage above the plan, on-demand ......... 0.0000 USD Total cost of the hour .................. 0.1700 USD Without the plan it would have cost ..... 0.2125 USD Saving for the hour ..................... 0.0425 USD (20 %)
Hour B: consumption above the commitment (the Friday peak, twice the tasks).
Usage valued at on-demand price ......... 0.4250 USD Covered by the plan (0.17 / 0.80) ..... 0.2125 USD -> billed at 0.1700 USD Excess ................................ 0.2125 USD -> billed at 0.2125 USD Total cost of the hour .................. 0.3825 USD Without the plan it would have cost ..... 0.4250 USD Saving for the hour ..................... 0.0425 USD (10 % of the hour's total)
Lesson: the excess is not penalised, it is simply paid at the normal price. Falling short on the commitment carries no punishment at all; it just means you are not getting the discount on that part.
Hour C: consumption below the commitment (Sunday small hours, environments switched off).
Usage valued at on-demand price ......... 0.1000 USD Valued at Savings Plan rate ........... 0.0800 USD Unused commitment ....................... 0.0900 USD <- PAID ANYWAY Total cost of the hour .................. 0.1700 USD Without the plan it would have cost ..... 0.1000 USD Loss for the hour ....................... 0.0700 USD
Here the whole risk is condensed. That hour has cost 70 % more than it would have cost without the plan. And it is not a far-fetched hypothesis: it is exactly what happens at night and at weekends as soon as the non-production environments are switched off, which is precisely what MercadoFresco has just done in 11-03.
From that comes the sizing rule that governs the whole decision: the commitment is set below the sustained minimum consumption of the quietest hour of the week, not by the average and far less by the peak.
What each plan covers and what it does not
This is the table to consult before buying anything, and the one that explains why MercadoFresco is going to save less than it expected:
| Service | Compute SP | EC2 Instance SP | Reserved Instances | Spot |
|---|---|---|---|---|
| EC2 | Yes | Yes | Yes | Yes |
| AWS Fargate | Yes | No | No | Yes (Fargate Spot) |
| AWS Lambda | Yes (duration, not invocations) | No | No | No |
| Amazon RDS / provisioned Aurora | No | No | Yes | No |
| Aurora Serverless v2 | No | No | No | No |
| Amazon ElastiCache | No | No | Yes (reserved nodes) | No |
| Provisioned Amazon Redshift | No | No | Yes | No |
| Redshift Serverless | No | No | No | No |
| Amazon OpenSearch | No | No | Yes | No |
| DynamoDB | No | No | Yes (reserved capacity, provisioned mode only) | No |
| S3, CloudFront, NAT, ALB, CloudWatch | No | No | No | No |
And here comes the uncomfortable conclusion for MercadoFresco, which is worth stating plainly because it is a general lesson:
A mostly serverless architecture has far less room for commitment discounts than one based on instances.
The concrete detail: aurora-mercadofresco-pedidos runs on Aurora Serverless v2, which is billed per ACU-hour and does not accept Reserved Instances. The same goes for wg-mercadofresco-analitica, which is Redshift Serverless. Between them they add up to 447.10 USD a month that cannot be committed in any way.
This is not bad news in disguise: it is the other side of a decision that already paid off. Serverless saved money earlier by scaling to zero when there is no load — remember the comparison in 06-04, where provisioned Redshift cost 1,586 USD a month against 16 for Serverless. You cannot charge for the same saving twice. A provisioned Redshift cluster with a three-year reservation would come out cheaper per hour and vastly more expensive per month, because it would be switched on for all 730 hours.
Reserved Instances: what Savings Plans cannot reach
For what Savings Plans do not cover and is provisioned, there are Reserved Instances (RIs). They work in a similar way but commit to specific resources, not to money per hour.
What MercadoFresco can reserve:
| Resource | State | Reservable? | Monthly cost | Potential saving |
|---|---|---|---|---|
mercadofresco-catalogo (ElastiCache, 2 × cache.t4g.medium) |
Provisioned 24/7 | Yes, reserved nodes | 108.83 USD | ~37 USD (34 %) |
aurora-mercadofresco-pedidos |
Serverless v2 | No | 342.60 USD | 0 |
wg-mercadofresco-analitica |
Redshift Serverless | No | 104.50 USD | 0 |
mercadofresco-carritos / -idempotencia |
DynamoDB on-demand | Not in that mode | 58.40 USD | 0 |
| Bastion host and leftover volumes | Already deleted in 11-03 | — | 0 | 0 |
Only one row is actionable, and it is the ElastiCache one. The cache nodes have been switched on for all 730 hours of the month for months, their size is validated and there is no plan to change them: it is the textbook case for a reservation.
Standard versus convertible, scope and capacity reservation
The options you have to decide on when buying a reservation:
| Decision | Options | Effect |
|---|---|---|
| Type | Standard: bigger discount, you cannot change family Convertible: smaller discount, can be exchanged for another of equal or greater value |
The convertible one costs about 5-10 points of discount and buys flexibility |
| Scope | Regional: applies to any AZ in the region, with size flexibility Zonal: fixed to one AZ, and reserves capacity |
Regional to save money; zonal only if you need a capacity guarantee |
| Capacity reservation | Only with zonal scope | Guarantees a machine will be available even if the AZ is full |
| Resale marketplace | Only for standard EC2 RIs, with a US bank account | Lets you sell what is surplus; does not apply to Savings Plans, or to RDS or ElastiCache |
Two warnings that avoid disappointment:
- Savings Plans cannot be sold or cancelled. The resale marketplace exists only for standard EC2 reservations. If you buy a Compute Savings Plan and have too much, you have too much for the whole term.
- Size flexibility only works within the same family and operating system. A
cache.t4g.mediumreservation coverscache.t4g.smallat half power, but it does not covercache.r7g.large.
For MercadoFresco: an ElastiCache reservation, standard, regional, 1 year, partial upfront. Standard because the size is validated and there is no intention of changing family; regional because there is no need to guarantee capacity; one year for the same reason as the Savings Plan.
Spot, revisited from the cost angle
Spot is spare AWS capacity sold at up to 90 % discount in exchange for being able to take it back with two minutes' notice. There is no commitment and no term: it is a price, not a contract.
MercadoFresco has been using it since 10-02, with the base=1, weight 1:4 split on svc-mercadofresco-trabajadores: one task always on-demand and the rest mostly on Fargate Spot. The criterion that decided where it fits still holds and is worth repeating, because it is what avoids disaster:
Spot goes only where an interruption with two minutes' notice retries itself and nobody notices.
Workloads that accept it in an architecture like this one:
| Workload | Spot? | Why |
|---|---|---|
| Queue workers with retry and DLQ | Yes | An unacknowledged message goes back to the queue |
| Thumbnail generation, batch processing | Yes | It retries with no visible effect |
| Nightly loads into Redshift | Yes, with retry | The window is wide |
| Development and test environments | Yes | An interruption is an inconvenience |
| Pipeline builds | With care | It stretches build times if interruptions are frequent |
| The shop's web service | No | An interruption during the Friday peak is exactly what we were trying to avoid |
| Database, cache | No | Not applicable; besides, state does not recover on its own |
And an important relationship with the above: Spot usage does not consume a compute Savings Plan commitment, because it is already billed with its own discount. Therefore, when calculating the stable base to commit against, Spot consumption is subtracted. Forgetting this leads to over-committing.
Identifying the stable base against the elastic portion
This is the analytical work that precedes any purchase. The question: how much eligible compute is switched on during the quietest hour of the week?
The tool is Cost Explorer's hourly view, filtered to Fargate and Lambda, excluding Spot, over the last four weeks. MercadoFresco's profile after the optimisations in 11-03:
| Time band | Description | USD/hour of eligible compute |
|---|---|---|
| Sunday small hours (03:00-06:00) | Production only, minimum tasks | 0.214 |
| Weeknights | Production at minimum; non-production switched off | 0.221 |
| Working hours | Normal production + pre-production + development | 0.392 |
| Shopping evening (17:00-21:00) | Production scaled up | 0.478 |
| Friday 17:00-21:00 | The peak: 900 orders/hour | 0.690 |
| Monthly average | 0.328 |
Three figures and three conclusions:
- The sustained minimum is 0.214 USD/hour. It is what is switched on at all times, without exception, including the Sunday small hours.
- The average is 0.328 USD/hour, 53 % above the minimum. Committing at the average would mean wasting commitment every night and every weekend.
- The peak is 0.690, more than three times the minimum. Committing at the peak would be a disaster.
The practical rule: commit to between 70 % and 85 % of the sustained minimum on the first plan. MercadoFresco chooses 0.17 USD/hour, which is 79 % of the minimum. That 21 % margin covers three specific risks:
- That something more than expected gets switched off over the coming months — there are optimisations still pending.
- That part of the compute moves to Spot and stops being eligible.
- That an architectural change reduces compute, as would happen if some workload moved to a service that is not covered.
Automatic recommendations and why they are not decisions
Cost Explorer offers purchase recommendations under Savings Plans → Recommendations, configurable by term, payment option and analysis period (7, 30 or 60 days).
For MercadoFresco, with 30 days and 1 year no upfront, the recommendation is:
Recommended commitment ................ 0.29 USD/hour Estimated monthly saving .............. 52.80 USD Estimated utilisation ................. 98 % Based on .............................. the last 30 days of usage
And MercadoFresco does not follow it. It buys 0.17, not 0.29. The reasons are instructive and hold for any case:
- The recommendation assumes the future will be like the past. The 30 days analysed include the first two weeks before the nightly shutdown in 11-03. The recommendation is calculated on consumption that no longer exists.
- It optimises expected saving, not risk. The algorithm looks for the point that maximises average saving; it does not know that there is a migration planned in three months, or that the team wants to try moving a workload to Lambda.
- The estimated 98 % utilisation is a monthly average, not an hourly guarantee. With the nights switched off, the real utilisation of a 0.29 commitment would be far worse than that number suggests.
- Nobody at AWS loses money if you over-commit. The recommendation is honest and well calculated, but the incentive is not aligned with yours.
The right way to use them: as a starting point and as a ceiling, never as a decision. If the recommendation says 0.29, you know that 0.29 is too much and that the answer lies below it. And you always cross-check it against your own hourly view, which is the data the recommendation cannot take into account: your knowledge of what is going to happen.
MercadoFresco's purchase plan
After the analysis, Marta takes a two-line proposal to management:
| Purchase | Product | Commitment | Term | Payment | Account |
|---|---|---|---|---|---|
| 1 | Compute Savings Plan | 0.17 USD/hour | 1 year | No upfront | Management 999988887777 |
| 2 | ElastiCache reserved nodes | 2 × cache.t4g.medium |
1 year | Partial | Production 111122223333 |
The justification for each decision, written up in ADR-024:
- Compute and not EC2 Instance, because MercadoFresco's compute is Fargate and Lambda, which the EC2 Instance plan does not cover at all.
- 0.17 USD/hour and not the recommended 0.29, because that is 79 % of the real sustained minimum after the optimisations.
- One year and not three, because in 10-03 six objective criteria were written down that would lead MercadoFresco to migrate to EKS, and two of them could be met within eighteen months. Committing for three years with a plausible migration on the horizon is exactly the mistake this lesson teaches you to avoid. With the nuance that a Compute Savings Plan would survive that migration — EKS on Fargate is still Fargate — but it would not survive a larger change of strategy.
- No upfront, because the 4 extra discount points from paying all upfront amount to about 5 USD a month in exchange for tying up 1,489 USD for a year. For a company of this size, cash is worth more.
- The purchase is made from the management account so that the discount is distributed automatically across the whole organisation through consolidated billing.
- The ElastiCache nodes do go with partial upfront, because the amount is small and the certainty is total: they have been switched on for ten months and there is no plan to touch them.
The purchase command — which in practice is run from the console after reviewing the summary twice, because there is no undo:
# 1. Check the current rate before committing
aws savingsplans describe-savings-plans-offerings \
--plan-types Compute \
--durations 31536000 \
--payment-options "No Upfront" \
--filters name=region,values=eu-west-1 \
--max-results 5
# 2. Create the plan. commitment is expressed in USD/hour.
# upfront-payment-amount is 0 with the no upfront option.
aws savingsplans create-savings-plan \
--savings-plan-offering-id "abcd1234-5678-90ef-ghij-klmnopqrstuv" \
--commitment "0.17" \
--upfront-payment-amount "0" \
--purchase-time "2026-10-01T00:00:00Z" \
--tags Proyecto=mercadofresco,Propietario=marta,CentroCoste=operaciones
# 3. ElastiCache reservation: first find the offering
aws elasticache describe-reserved-cache-nodes-offerings \
--cache-node-type cache.t4g.medium \
--duration 31536000 \
--offering-type "Partial Upfront" \
--product-description redis
# 4. Buy it, with an identifier of our own so it can be traced
aws elasticache purchase-reserved-cache-nodes-offering \
--reserved-cache-nodes-offering-id "1a2b3c4d-5e6f-7890-abcd-ef1234567890" \
--reserved-cache-node-id "ri-mercadofresco-catalogo-2026" \
--cache-node-count 2Three notes on these commands:
--commitmentis USD per hour, not monthly or annual. Writing170instead of0.17would buy a commitment a thousand times larger, and there is no way to undo it. It is the most expensive mistake you can make in this entire lesson.--duration 31536000is the number of seconds in a year. Three years is94608000.- Tagging the purchase lets you see it in reports with the same dimensions as everything else. Yes: even a financial commitment gets tagged.
Before and after
| Item | Before committing | After | Difference |
|---|---|---|---|
| Eligible compute (Fargate + Lambda) | 239.60 USD | 208.60 USD | −31.00 USD |
| ElastiCache | 108.83 USD | 71.83 USD | −37.00 USD |
| Rest of the bill | 1,401.17 USD | 1,401.17 USD | 0 |
| Monthly bill | 1,749.60 USD | 1,681.60 USD | −68.00 USD (−3.9 %) |
| Annualised saving | −816 USD | ||
| Cost per order | 0.00972 USD | 0.00934 USD | −3.9 % |
And the module's complete balance, which is the figure taken to management:
| Milestone | Monthly bill | Cost per order |
|---|---|---|
| Starting point (11-03) | 2,237.60 USD | 0.01243 USD |
| After the ten optimisations (11-03) | 1,749.60 USD | 0.00972 USD |
| After the commitments (11-05) | 1,681.60 USD | 0.00934 USD |
| Total reduction | −556.00 USD (−24.8 %) | −24.8 % |
| Annualised saving | −6,672 USD |
The proportion is worth pointing out, because it is the lesson most often repeated in practice and least often told: of the 556 USD of savings, 488 come from switching off and cleaning up, and only 68 from committing. In other words, 88 % of the saving was achieved without signing anything. In a mostly serverless architecture, commitments are the garnish, not the main course.
Coverage and utilisation: two different things
They are constantly confused and they measure opposite things:
| Metric | Formula | What it means | Target |
|---|---|---|---|
| Utilisation | Commitment used ÷ commitment purchased | How much of what you pay for you are actually using | 99-100 % |
| Coverage | Usage covered by the plan ÷ total eligible usage | How much of your consumption enjoys the discount | 60-80 % |
The key is that 100 % utilisation is compulsory and 100 % coverage is a mistake:
- Utilisation below 100 % means you are paying for commitment you do not use. Every point lost is money thrown away. If it drops below 95 %, it needs investigating.
- 100 % coverage would mean that all your consumption, including the Friday peak, is committed. Since the peak is not sustained, to get there you would have had to commit far above the base, and you would be losing money every night.
For MercadoFresco, with a commitment of 0.17 against an average of 0.328:
Expected utilisation ... ~100 % (the sustained minimum is 0.214 > 0.17) Expected coverage ...... ~65 % (0.2125 covered / 0.328 average)
Coverage of 65 % with 100 % utilisation is exactly the right point: everything committed is being used and the variable portion stays on on-demand, which is where it belongs.
Monitoring and alarms
A commitment that is bought and not watched is a silent leak. Three mechanisms, in order of importance:
1. A Savings Plans utilisation budget (11-04), which is the most direct approach:
{
"BudgetName": "pres-mf-utilizacion-sp",
"BudgetType": "SAVINGS_PLANS_UTILIZATION",
"TimeUnit": "MONTHLY",
"BudgetLimit": { "Amount": "95", "Unit": "PERCENTAGE" }
}With an ACTUAL notification, operator LESS_THAN and threshold 95: it warns when utilisation falls below that percentage. It is one of the few legitimate uses of LESS_THAN in a budget, and here it is indispensable.
2. Utilisation and coverage reports in Cost Explorer, reviewed at the monthly meeting alongside everything else. Two charts you can read in ten seconds that tell the whole story.
3. An expiry warning ninety days before the plan runs out. Savings Plans do not renew themselves: the day they expire, all consumption goes back to on-demand price at once and the bill rises without anybody having done anything. An EventBridge rule on the expiry date, or simply a calendar entry, avoids that surprise. Renewal is also the ideal moment to rethink the commitment with a year of real data on the table.
What to do if the architecture changes
The scenario to anticipate before signing. Suppose MercadoFresco had bought a 3-year EC2 Instance Savings Plan in 2024 on the m5 family in eu-west-1, sized for its ASG at the time. And that in 2026, following module 10, it migrates the whole shop to Fargate on arm64.
The result: the commitment stops applying entirely. It does not cover Fargate, it does not cover Graviton outside its family, and there would be a year left paying for capacity that is not used. On a commitment of about 150 USD a month, that would be 1,800 USD thrown away and, worse still, a perverse incentive to delay the migration so as not to waste the plan. That is the real damage of a badly chosen commitment: it does not only cost money, it conditions technical decisions.
Hence MercadoFresco's three rules:
- Compute Savings Plan by default, even if it gives slightly less discount. It survives most changes: EC2 to Fargate, x86 to arm64, a change of region, part of the work to Lambda.
- One year while there is any plausible change on the horizon. Three years only for the part of the architecture that has not moved in years and has no alternative in sight.
- Before committing, review the architecture decision record (11-01). If there is an ADR that contemplates a change in the next two years, that change affects the purchase decision.
And if the plan still ends up unused, the options are few and worth knowing in advance: a Compute Savings Plan cannot be cancelled, reduced or sold. The only thing you can do is put it to use: move workloads to covered services, bring forward migrations that were already planned, or leave something switched on that was going to be switched off — which is absurd, but is exactly what people end up doing.
Sharing commitments across accounts
With consolidated billing (09-04), a Savings Plan bought in any account applies to the usage of every account in the organisation, starting with the one that bought it and continuing with the rest in order of highest discount.
This behaviour is controlled with the discount sharing setting, configured in the billing preferences of the management account:
| Setting | Effect | When to use it |
|---|---|---|
| Sharing enabled (default) | The plan covers usage across all accounts | When the organisation is a single company with a single budget |
| Sharing disabled for one account | That account neither benefits nor contributes | When a business unit buys and pays for its own |
MercadoFresco leaves it enabled, which is the right choice in its case: there is a single budget and the goal is for the commitment to be used to the full, wherever the consumption comes from. With two consequences worth keeping in mind:
- The discount shows up in the account that consumes, not in the one that bought. The amortised cost from 11-03 is the metric that reflects this properly; unblended cost does not.
- Buying from the management account is the recommended practice for precisely that reason: management consumes almost nothing, so the commitment spreads to wherever there really is usage, and ownership of the contract sits where financial control is.
Expensive mistakes
The three that ruin a purchase, in order of frequency:
1. Committing before optimising. This is the ordering mistake and the most expensive of them all. If MercadoFresco had bought a Savings Plan in August, on compute consumption of 262.40 USD, and in September had carried out the ten optimisations from 11-03 — which cut that consumption by 24 % — the surplus commitment would be paid for the whole term. The right order admits no exceptions: first switch off what is surplus, then size what is left, and only then commit.
2. Committing too much. It comes from sizing on the average or on the automatic recommendation instead of on the sustained minimum. The symptom is utilisation below 100 % from the first month, and there is no fix until expiry.
3. Confusing coverage with utilisation. Somebody sees 65 % coverage and concludes that they should buy more. It is exactly the other way round: 65 % coverage with 100 % utilisation is fine; raising coverage to 90 % would require committing above the sustained minimum and would push utilisation down. The right question is never "how much coverage do I have?" but "am I using everything I pay for?".
Common Mistakes and Tips
Mistake: buying an EC2 Instance Savings Plan when the workload is in containers. It gives more discount on paper and covers exactly zero of your consumption. Tip: check the coverage table before looking at the percentages. Fargate and Lambda are only covered by Compute.
Mistake: writing the commitment in the wrong units. --commitment is USD per hour. Entering the monthly amount multiplies the commitment by 730 and there is no undo. Tip: review the purchase summary twice and compare it with your hourly view before confirming.
Mistake: sizing by the average. MercadoFresco's average is 0.328 and its sustained minimum 0.214. Committing at the average means wasting money every night and every weekend. Tip: the commitment is set at between 70 and 85 % of the sustained minimum.
Mistake: buying a three-year term on the first purchase. The discount is seductive and the term outlasts the average life of an architectural decision. Tip: first plan at one year; at renewal, with real data, you can consider the long term for the part that has demonstrably been stable.
Mistake: including Spot consumption in the base calculation. Spot already has its discount and does not consume commitment, so committing against it is committing against nothing. Tip: exclude Spot from the hourly view filter before calculating the minimum.
Mistake: expecting the plan to cover RDS, ElastiCache or Redshift. None of the three types covers them. Tip: that is what Reserved Instances are for, and only if the resource is provisioned: Serverless does not accept reservations.
Mistake: forgetting the expiry date. The plan expires, everything goes back to on-demand price and the bill rises without anybody having touched anything. Tip: a warning 90 days in advance, and renewal treated as a fresh decision, not as a formality.
Mistake: letting the commitment condition the architecture. "We are not migrating yet because we would waste the plan" is a sentence you hear far too often. Tip: if a badly chosen commitment is holding back a sound technical decision, take the loss and move on. The cost of a worse architecture for two years far exceeds that of a wasted plan.
Tip: buy from the management account and leave sharing enabled. That is what makes the commitment get used where the consumption really is.
Tip: write an ADR for the purchase. A one- or three-year commitment is an architectural decision with financial consequences: it deserves the same treatment as any other, with its discarded alternatives and its review date.
Exercises
Exercise 1: sizing a commitment
A fictitious company, TallerNube, has this eligible compute profile (EC2 and Fargate, excluding Spot) measured over four weeks:
| Time band | USD/hour | Hours per week |
|---|---|---|
| Sustained minimum (nights and weekends) | 1.10 | 96 |
| Working hours | 2.40 | 55 |
| Month-end closing peak (2 days a month) | 4.80 | 17 |
- Calculate the hourly average for the month and compare it with the minimum.
- Propose a commitment and justify the percentage chosen.
- With a 22 % discount, calculate the monthly and annual saving.
- AWS's automatic recommendation proposes 1.95 USD/hour. Would you follow it? Why?
Exercise 2: choosing a product for each workload
For each of these workloads, state which purchase model you would use and why:
- A provisioned Aurora cluster,
db.r6g.largeMulti-AZ, switched on 24/7 for the past two years. - A Fargate service that scales between 2 and 20 tasks depending on the hour.
- A nightly data transformation job that takes 3 hours and can be retried.
- A Redshift Serverless cluster used 2 hours a day.
- A fleet of 40
m6i.xlargeinstances that have not changed in three years and are not expected to migrate. - A Lambda function invoked 4 million times a month with an average duration of 200 ms.
Exercise 3: diagnosing a sick commitment
Three months after buying a one-year Compute Savings Plan of 0.30 USD/hour, the reports show:
Average utilisation for the month ..... 78 % Average coverage for the month ........ 71 % Unused commitment ..................... 48.20 USD for the month
- What is the problem and what is not?
- List three possible causes, ordered by likelihood.
- What options are there to fix it and which would you recommend?
Solutions
Solution to exercise 1
(1) Hourly average. Over a typical 168-hour week, with the peak spread out (17 hours a month ≈ 4 hours a week, taken out of working hours):
Sustained minimum: 1.10 x 96 h = 105.60 Working hours: 2.40 x 51 h = 122.40 Month-end peak: 4.80 x 4 h = 19.20 -------------------------------------------- Weekly total = 247.20 USD Hourly average: 247.20 / 168 = 1.471 USD/hour
The average (1.471) is 34 % above the sustained minimum (1.10). Committing at the average would mean wasting 0.371 USD/hour during the 96 quiet hours each week: some 39.7 USD a week thrown away, more than 170 USD a month.
(2) Proposed commitment: 0.88 USD/hour, which is 80 % of the sustained minimum. The 20 % margin covers the foreseeable: some workload moving to Spot, an environment being switched off, or a pending optimisation reducing the base consumption. If TallerNube has already done all its optimisations and has a firm growth forecast, it could go up to 0.93 (85 %), but no higher on a first purchase.
(3) Saving with a 22 % discount:
Commitment ................. 0.88 USD/h On-demand usage covered ... 0.88 / 0.78 = 1.128 USD/h Saving per hour ........... 1.128 - 0.88 = 0.248 USD/h Monthly saving ............ 0.248 x 730 = 181.04 USD Annual saving ............. 2,172.48 USD
(4) The recommendation of 1.95 USD/hour is not followed. It is above even the hourly average (1.471) and almost double the sustained minimum (1.10). With that commitment, TallerNube would pay 0.85 USD/hour of unused commitment during the 96 quiet hours each week — some 353 USD a month thrown away — which would far exceed the saving obtained during the busy hours. It is a perfect example of why the recommendation is a starting point and not a decision: it is probably calculated over a period containing an atypical peak, or it is optimising expected saving without weighing the risk of the quiet hours.
Solution to exercise 2
| Workload | Model | Justification |
|---|---|---|
| 1. Provisioned Aurora 24/7, two years | Reserved Instance, standard, 3 years, partial upfront | No Savings Plan covers RDS. It is provisioned, it has been stable for two years and there is no plan to change it: the ideal case for a long term. If there were any intention of moving to Serverless v2, it would be 1 year |
| 2. Fargate from 2 to 20 tasks | Compute Savings Plan on the base of 2 tasks + on-demand for the rest | The base is sustained and eligible; the elastic portion is paid on-demand, which is where it belongs. Never commit against the 20 |
| 3. Retryable nightly job | Spot | It tolerates interruptions with retry and the time window is wide. Up to 90 % discount with no commitment. Careful: it does not count towards the Savings Plan base |
| 4. Redshift Serverless, 2 h a day | On-demand, nothing else | Serverless does not accept reservations, and even if it did, with 2 hours of usage a day any commitment would be ruinous. The saving here is already in having chosen Serverless |
5. 40 × m6i.xlarge, three years unchanged |
EC2 Instance Savings Plan, 3 years, all or partial upfront | It is the only case on the list where the EC2 Instance plan wins: fixed family, fixed region, a demonstrated history of stability and enough volume for the extra 6-8 points to be real money |
| 6. Lambda, 4 M invocations | Compute Savings Plan, if there is a sustained base | Compute covers Lambda duration (GB-second), not invocations. With 4 M a month and 200 ms, duration is the bulk of the cost. If the pattern is very irregular, on-demand is better |
The cross-cutting observation from this exercise: out of six workloads, four different models. There is no such thing as "the best purchase model", there is the right one for each consumption profile.
Solution to exercise 3
(1) What the problem is. The problem is the 78 % utilisation: 22 % of the commitment is being paid for with nothing in return, some 48.20 USD a month, which is 578 USD if it carries on like that all year. The 71 % coverage is not a problem at all; in fact it sits in the reasonable band. Anyone looking only at coverage will conclude that everything is fine, and that is precisely the confusion this lesson warns about.
(2) Three possible causes, by likelihood:
- The commitment was set above the sustained minimum, probably by sizing on the average or by following the automatic recommendation. It is by far the most frequent cause, and the characteristic symptom is that utilisation is bad from the very first month.
- Something was switched off or optimised after the purchase: an environment with a nightly shutdown, a migration to arm64, a workload moved to Spot or to a service that is not covered. The symptom would be good utilisation at first that gets worse at an identifiable moment.
- Part of the compute stopped being eligible: it moved to Spot — which does not consume commitment — or to a service the plan does not cover, such as moving a batch job from Fargate to AWS Batch on Spot capacity.
To tell them apart it is enough to look at the utilisation time series since the purchase: flat and low points to cause 1; a step change points to 2 or 3, and the date of the step says what happened.
(3) Options and recommendation. The real options are few, because a Savings Plan cannot be cancelled, reduced or sold:
| Option | Feasibility | Comment |
|---|---|---|
| Cancel or sell the plan | Impossible | There is no secondary market for Savings Plans |
| Put the commitment to use by moving workloads to covered services | Possible and advisable | Bring forward migrations to Fargate or Lambda that were already planned; move back to on-demand some workload that was on Spot and did not need to be |
| Leave something switched on that was going to be switched off | Possible and inadvisable | It consumes the commitment but worsens the architecture and sustainability; it only makes sense if that resource provided real value |
| Take the loss and wait for expiry | Always available | 578 USD of sunk cost, with the lesson learned |
Recommendation: a combination of the second and the fourth. First, check whether there are migrations already planned towards covered services that could be brought forward; that turns wasted commitment into a real discount without distorting any decision. Whatever is left, you absorb. And above all, write down why so that the renewal does not repeat the mistake: commitment at 75-80 % of the sustained minimum, calculated on data from after the optimisations and excluding Spot.
What you must not do under any circumstances is stop optimising in order to "get your money's worth" from the plan. That would be exactly the perverse incentive this lesson warns about: the commitment would go from being a savings tool to being a brake on the architecture.
Conclusion
MercadoFresco has closed the optimisation cycle with the only lever that reduces the bill without touching a single line of the architecture.
You know why the commitment discount exists — AWS builds data centres in advance and pays for a forecast of demand — and the four consequences that follow on their own from that logic: a longer term, more upfront payment and less flexibility give more discount, and the risk shifts entirely to the customer. Along with the four purchase models and the decision tree that orders them: Spot if the workload tolerates interruptions, on-demand if consumption is unpredictable, Savings Plans for EC2, Fargate and Lambda, and Reserved Instances for everything else that is provisioned.
You have the three types of Savings Plans with the comparison that really matters: the EC2 Instance one gives 6-8 points more and ties you to one family and one region; the Compute one gives slightly less and survives changes of instance, region, CPU architecture and service. And you know why for MercadoFresco there is no debate: its compute is Fargate and Lambda, which the EC2 Instance plan does not cover at all.
You genuinely understand the mechanism of the dollar-per-hour commitment, with the three hours of the example: the hour that consumes exactly what was committed and saves 20 %, the peak hour where the excess is not penalised and is simply paid at the normal price, and the small-hours hour where the unused commitment is paid anyway and makes that hour cost 70 % more than it would have without the plan. Hence the rule that governs everything: you size by the sustained minimum of the quietest hour of the week, never by the average and far less by the peak.
You have the coverage table and the uncomfortable conclusion that follows from it for an architecture like this one: the 342.60 USD of Aurora Serverless v2 and the 104.50 of Redshift Serverless cannot be committed in any way. And its correct interpretation, which is not a complaint: serverless already collected that saving in advance, by scaling to zero when there is no load, and you cannot charge for the same saving twice.
You have Reserved Instances for what the plans cannot reach, with their decisions — standard versus convertible, regional versus zonal scope, capacity reservation, a resale marketplace only for standard EC2 RIs — and Spot revisited from the cost angle, with the criterion that decides where it fits and the detail people forget: Spot consumption does not consume commitment, so it is subtracted when calculating the base.
You have the complete analysis: MercadoFresco's hourly profile with its sustained minimum of 0.214 USD/hour, its average of 0.328 and its peak of 0.690; the 70-85 % of the minimum rule; and the reason why 0.17 is bought and not the 0.29 recommended by AWS, with the four reasons that make an automatic recommendation a starting point and never a decision, beginning with the most decisive one: it assumes the future will be like the past, and that past included consumption the optimisations in 11-03 had just eliminated.
You have the purchase plan with its ADR: a Compute Savings Plan of 0.17 USD/hour for one year with no upfront from the management account, plus two ElastiCache reserved nodes for one year with partial upfront. And the result: 68.00 USD a month, 816 USD a year, leaving the bill at 1,681.60 USD and the cost per order at 0.00934 USD. With the module's complete balance — from 2,237.60 to 1,681.60 USD, a 24.8 % reduction and 6,672 USD a year — and the proportion never to be forgotten: 88 % of the saving came from switching off and cleaning up, and only 12 % from committing.
And you have the monitoring: coverage and utilisation as opposing metrics, with the rule that orders them — utilisation should be 100 % and coverage should not be — the SAVINGS_PLANS_UTILIZATION budget with the LESS_THAN operator at 95 %, the expiry warning ninety days in advance because plans do not renew themselves, the sharing across accounts with discount sharing enabled, and the three expensive mistakes: committing before optimising, committing too much, and confusing coverage with utilisation. Plus the less obvious and more serious damage of a badly chosen commitment: that it conditions technical decisions, turning "we are not migrating so as not to waste the plan" into a sentence somebody says in earnest.
With this, the cost optimisation pillar that opened the improvement plan in 11-01 is closed: there is visibility, there is allocation, there is analysis, there are limits and there are commitments. The bill is readable, it is under control and it costs 24.8 % less than two months ago, with the same service and the same guarantees.
And with that, MercadoFresco has a complete, governed architecture: elastic, secure, observable, deployable, described in code, spread across five accounts, audited with a method and now measured and budgeted too. Eleven modules of decisions, each one with its reason.
One last thing remains to be done, and it is not learning a new service. In 11-06, the final project, we walk through MercadoFresco's entire architecture linking each piece to the module where it was learned, we close the balance on the five problems that opened the course with their metrics, and we set the challenge that pulls it all together: MercadoFresco opens in Portugal and France and launches a mobile app with real-time delivery tracking. With its brief, its rubric, an annotated reference solution, the certification paths, what this course has not touched, and the final clean-up of everything created.
AWS Course
Module 1: Introduction to AWS
- What Is AWS?
- Setting Up Your AWS Account
- AWS Global Infrastructure
- The AWS Management Console
- AWS CLI and SDKs
Module 2: Core AWS Services
Module 3: Networking and Content Delivery
Module 4: Security and Identity
- AWS Identity and Access Management (IAM)
- AWS Key Management Service (KMS)
- Secrets Manager and Parameter Store
- AWS Shield
- AWS WAF
Module 5: Monitoring and Management
Module 6: Databases
Module 7: Application Integration
- Amazon SQS
- Amazon SNS
- Amazon EventBridge
- AWS Step Functions
- Integration Patterns: Idempotency, Retries and Dead-Letter Queues
