The final part turns the 28 case studies into an executable plan: a 90-day playbook (See, then Stop and shrink, then Swap and flex, then Redesign and commit), the operating rhythm that keeps savings from eroding (weekly, monthly, quarterly rituals and the cost estimate in every design document), the KPIs worth tracking (unit cost, commitment utilisation and coverage, tag coverage, waste ratio, time to detect anomalies), and concrete checks for a DevSecOps platform team running multi-cloud Kubernetes, HashiCorp Vault, Argo CD and Terraform GitOps, PostgreSQL with pgBackRest on S3, SQL Server Always On availability groups and GitHub Enterprise CI, including how to use an LLM safely as a read-only cost-forensics assistant. It closes with where security and cost overlap, which is the easiest way to win support from both teams.
Get the full report. This series expands the research report Cutting the AWS Bill: 28 Case Studies (53 pages, PDF, 780 KB). One click starts the download.
⬇ Download PDF1. From stories to a plan
Eight parts of stories, arithmetic and reference tables converge on one question: what do I do on Monday? The answer in the report is a sequence, not a list. The order matters because each step makes the next one smaller or safer: you cannot right-size what you cannot see, you should not commit to what you have not shrunk, and you should not redesign a path you have not measured.
Fig. 1 - The sequence, not the list, is the plan.
2. Days 1-7: See
- Enable CUR 2.0 / Data Exports to S3 and query with Athena (or load into your warehouse). This is the Segment, Lyft and Airbnb move (Part 2).
- Agree a tag schema (owner, service, environment, cost-centre) and enforce it with tag policies and infrastructure-as-code checks.
- Turn on Cost Anomaly Detection and per-team budgets. Duolingo's automated anomaly detection catches regressions within days.
- Create a read-only analysis role; optionally let an LLM agent use it to answer precise questions (the Levels.fyi Part 2 method, with safeguards in section 8).
- Pick one unit-cost metric and publish its baseline. Cost per ride, per event, per active user or per GB.
A minimal starting query ranks the top movers. Confirm column names against your own export.
WITH monthly AS (
SELECT line_item_product_code AS service,
date_trunc('month', line_item_usage_start_date) AS month,
SUM(line_item_unblended_cost) AS cost
FROM cur_table
WHERE line_item_usage_start_date >= DATE '2026-06-01'
GROUP BY 1, 2
)
SELECT service,
MAX(CASE WHEN month = DATE '2026-08-01' THEN cost END) AS aug,
MAX(CASE WHEN month = DATE '2026-07-01' THEN cost END) AS jul,
MAX(CASE WHEN month = DATE '2026-08-01' THEN cost END)
- MAX(CASE WHEN month = DATE '2026-07-01' THEN cost END) AS delta
FROM monthly
GROUP BY 1
ORDER BY delta DESC NULLS LAST
LIMIT 20;
3. Weeks 2-4: Stop and shrink
- Delete idle instances, unattached EBS, old snapshots, unused load balancers, Elastic IPs and public IPv4 addresses.
- Set CloudWatch log retention everywhere; remove payload and stack-trace logging; filter WAF/CDN logs.
- Add S3 lifecycle rules: noncurrent versions, incomplete multipart uploads, cold-data transitions (Part 3).
- Add S3 and DynamoDB gateway endpoints; migrate gp2 to gp3; add ECR lifecycle policies.
- Schedule non-production to working hours, with a wake-up path (Part 5).
4. Weeks 4-8: Swap and flex
- Right-size with Compute Optimizer and container request data; lower minimum task counts.
- Run a Graviton pilot on the largest compute consumer; build multi-arch images (Part 4).
- Evaluate Aurora I/O-Optimized, DynamoDB capacity modes and table classes.
- Move CI/CD and batch to Spot; adopt Karpenter with consolidation where workloads are ready (Part 5).
5. Weeks 8-12: Redesign and commit
- Fix the top three chatty paths: hairpins, cross-AZ fan-out, per-request inner loops (Part 6).
- Run storage-class migrations ranked by payback period.
- Buy Compute and Database Savings Plans on the new baseline, laddered.
- Write a one-page retention policy and encode it in Terraform modules.
| Phase | Verbs | Risk | Typical reversibility |
|---|---|---|---|
| Days 1-7 | See | Very low | Fully reversible |
| Weeks 2-4 | Stop, shrink | Low (with snapshots) | Mostly reversible |
| Weeks 4-8 | Swap, flex | Medium | Reversible with a warm old pool |
| Weeks 8-12 | Redesign, commit | Higher | Commitments are one to three years |
6. Keeping the savings: the operating rhythm
Savings erode. New services arrive, retention drifts, someone scales a staging environment up for a test. The teams that kept their results left behind a rhythm, not just a set of changes.
| Cadence | Ritual |
|---|---|
| Weekly | Anomaly review; top movers by service and team; check the unit-cost trend |
| Monthly | Showback per team; review the waste list; celebrate wins publicly (Lyft-style leaderboards) |
| Quarterly | Commitment coverage and utilisation; architecture review of the top five line items; retention audit |
| Every design doc | A cost estimate per unit of work and a retention section (Duolingo practice) |
6.1 KPIs worth tracking
| KPI | Definition | Healthy target |
|---|---|---|
| Unit cost | Spend / business unit (ride, event, active user, GB) | Falling quarter over quarter |
| Commitment utilisation | Used commitment / purchased commitment | Above 95% |
| Commitment coverage | Discounted eligible usage / eligible usage | 70-85% of the steady baseline |
| Tag coverage | Spend with owner and service tags / total | Above 95% |
| Waste ratio | Idle + orphaned + unattached spend / total | Below 5% |
| Time to detect anomalies | Days from cost jump to owner notified | Under 2 days |
| Graviton and Spot share | Share of eligible compute on Graviton / Spot | Rising |
Two of these deserve emphasis. Tag coverage is the enabler of everything else: without it you cannot attribute spend to owners, and Lyft-style leaderboards and showback are impossible. Time to detect anomalies is the metric that would have caught Levels.fyi's creeping $26-then-$36-then-$41 line item in days instead of months.
7. Applying this to a multi-cloud platform team
The report ends with a chapter written for a platform stack built on EKS (alongside OKE and GKE), HashiCorp Vault, Argo CD, Terraform, PostgreSQL with pgBackRest on S3, SQL Server Always On availability groups on AWS and GitHub Enterprise CI. The checks below are ordered roughly by effort and each maps back to a case.
7.1 Kubernetes (EKS first; OKE and GKE have equivalents)
- Right-size pod requests from real usage (VPA recommender or Goldilocks) before touching node autoscaling.
- Adopt Karpenter with consolidation for stateless workloads and CI runners; add PodDisruptionBudgets and SIGTERM handling first (the Tinybird lesson).
- Create Graviton node pools and build multi-arch images in CI (the Honeycomb lesson).
- Keep every cluster on a standard-support Kubernetes version to avoid extended-support control-plane fees, and count clusters: each carries a fixed hourly fee.
- Enable topology-aware routing for chatty Services; add ECR and S3 endpoints so image pulls skip NAT.
- On GKE and OKE, the same ideas apply through Spot VMs, preemptible instances and flexible shapes.
7.2 PostgreSQL backups with pgBackRest on S3
- Apply the Levels.fyi lesson: write down the retention you actually need (full, differential and WAL retention) and configure pgBackRest expiry to match it, rather than keeping everything.
- If the repository bucket has versioning enabled, expire noncurrent versions and abort incomplete multipart uploads; otherwise expired backups keep costing money.
- Route WAL archiving and backup traffic from private subnets through an S3 gateway endpoint to avoid NAT processing fees.
- Be careful with lifecycle transitions on the repository prefix: objects that pgBackRest expires early may incur minimum-duration charges in IA or Glacier classes. Do the payback maths first.
- Use compression in pgBackRest and keep a cross-region copy only if your DR requirement actually demands it.
A configuration sketch showing where the retention decision lives (option names as in pgBackRest; verify against your version and set the values from your own recovery objectives):
[global]
repo1-type=s3
repo1-s3-bucket=example-pg-backups
repo1-s3-region=eu-west-1
repo1-path=/pgbackrest
compress-type=zst
# the retention decision, written down and enforced
repo1-retention-full=4
repo1-retention-full-type=count
repo1-retention-diff=7
repo1-retention-archive=4
repo1-retention-archive-type=full
The point is not these particular numbers but that they are explicit, reviewed and tied to a recovery requirement, so the bucket cannot quietly grow past the size of the databases it protects, which is exactly what happened at Levels.fyi (15.7 TB of backups).
7.3 SQL Server Always On on AWS
- Licensing often costs more than the compute. Re-check edition (Standard vs Enterprise), vCPU counts and whether license-included or bring-your-own licensing is cheaper for each node.
- For BYOL, the EC2 "Optimize CPUs" option can reduce active cores (and per-core licences) on memory-heavy instances.
- Confirm the licensing position of passive secondary replicas with your Microsoft agreement; rules vary.
- Measure cross-AZ replication traffic; synchronous replicas across AZs are billed for data transfer in both directions.
- Compare gp3 with provisioned IOPS against io2 for data and log volumes.
7.4 Vault, observability and GitOps
- Right-size Vault nodes (often over-provisioned) and run them on gp3; Vault ships arm64 builds for Graviton.
- Route high-volume audit logs to S3 with lifecycle rules instead of premium log ingestion, keeping what compliance requires.
- Encode cost guard rails in Terraform modules: default gp3, mandatory tags, S3 lifecycle rules, log retention, no public IPv4 by default. Enforce with policy-as-code in CI.
- Show a cost diff on infrastructure pull requests so reviewers see the price of a change.
- Use Argo CD to reconcile scheduled scale-down for non-production namespaces.
A Terraform module fragment that bakes several guard rails in, so a new bucket cannot exist without a lifecycle policy (resource names follow the AWS provider; adapt to your module conventions):
resource "aws_s3_bucket_lifecycle_configuration" "this" {
bucket = aws_s3_bucket.this.id
rule {
id = "expire-noncurrent"
status = "Enabled"
filter {}
noncurrent_version_expiration { noncurrent_days = 30 }
}
rule {
id = "abort-incomplete-mpu"
status = "Enabled"
filter {}
abort_incomplete_multipart_upload { days_after_initiation = 7 }
}
}
resource "aws_cloudwatch_log_group" "this" {
name = var.log_group_name
retention_in_days = var.log_retention_days # no default of "never"
tags = var.required_tags # owner, service, env, cost-centre
}
7.5 CI/CD and GitHub Enterprise runners
- Run self-hosted runners on Spot and arm64 with autoscaling runner sets; CI is the safest Spot workload (Lyft, Tinybird).
- Set artifact and cache retention; cache container layers to reduce repeated NAT egress for base images.
8. LLM-assisted cost forensics, safely
Levels.fyi's second round gave an LLM read-only AWS credentials and asked it precise, measurable questions: which log groups grew fastest last month and who writes to them; what pushed an RDS line item up a little every day. The result was faster than manual digging. The method transfers, but it needs guard rails because an agent with credentials is a new attack surface.
- Create a dedicated read-only role (Cost Explorer, CUR via Athena, CloudWatch read) with no write permissions, and block writes with an SCP as a second layer.
- Log every call with CloudTrail, and keep CUR data out of prompts sent to external services unless policy allows it.
- Ask measurable questions: which log groups grew fastest last month and who writes to them; which line items grew every day for 30 days; which NAT gateways moved the most bytes and to where.
- Verify the answers. Reproduce any claimed saving from list prices (Part 8, section 9.7) before acting on it.
9. Where security and cost overlap
Several savings in this series also shrink attack surface: private paths instead of public edges (Levels.fyi's PrivateLink move), fewer public IPv4 addresses, filtered WAF logs that make real attacks easier to see, and deleting forgotten instances and caches that nobody patches. Framing cost work as hygiene makes it easier to win support from both security and finance.
| Cost action | Security benefit |
|---|---|
| Delete forgotten instances and caches | Fewer unpatched, unowned hosts |
| PrivateLink and endpoints instead of public edges | Less internet exposure for internal calls |
| Fewer public IPv4 addresses | Smaller scan and attack surface |
| Filter WAF logs to blocked or suspicious requests | Real attacks are easier to see |
| Tag policy with mandatory owner | Every resource has someone to page |
| Defined retention policy | Easier audits; less stale sensitive data |
10. Your first week, concretely
- Day 1: enable Data Exports; create the Athena table; run the ranking query above for the last three months.
- Day 2: publish the top ten line items and their owners; where there is no owner, that is finding number one.
- Day 3: agree the tag schema and turn on Cost Anomaly Detection and per-team budgets.
- Day 4: pick the unit metric and publish its baseline value.
- Day 5: choose three "stop" targets (idle instances, log retention, versioned buckets), each with a snapshot and a named approver.
- Day 6-7: write the one-page retention table and schedule the first weekly anomaly review.
Can we skip straight to Savings Plans to get a quick win?
You can, but you will discount waste for one to three years. The playbook puts commitments in weeks 8-12, on the new, smaller baseline, laddered. If leadership needs a quick number, show the payback of the stop-and-shrink work first.
How big a team do we need?
Segment did it with two engineers over three months; Duolingo used dozens of engineers supported by a five-person FinOps team; Levels.fyi's second round was a small team. Scale to your bill, but keep one owner per phase.
How do we stop savings from eroding?
Leave a mechanism behind: tag policy, anomaly alerts, a weekly review, a cost estimate in every design doc, guard rails in Terraform modules, and a unit-cost metric someone watches. Without these, staging environments get scaled up and never scaled back.
Takeaways
- The sequence is the plan: See, Stop and shrink, Swap and flex, Redesign and commit.
- Leave a rhythm behind: weekly anomaly review, monthly showback, quarterly commitment and retention review, and a cost estimate in every design doc.
- Track seven KPIs, starting with unit cost, tag coverage and time to detect anomalies.
- Encode guard rails in Terraform modules so waste cannot be created by default.
- Use an LLM as a read-only assistant with a control and verify its answers against list prices.
- Frame cost as hygiene; it wins support from both finance and security.
References & further reading
- Cutting the AWS Bill: 28 Case Studies (PDF) - sections 8 (90-day playbook), 9 (platform team) and 10 (sources and method) are the basis of this part.
- AWS Cost Anomaly Detection · AWS Compute Optimizer
- Karpenter documentation · pgBackRest configuration reference
- Levels.fyi Part 2 - LLM-assisted forensics in practice
- Series index: Cutting the AWS Bill - all nine parts and the PDF download.
Keep it offline. The complete 28-case report, with the scoreboard, lever matrix and 90-day playbook, is one PDF.
⬇ Download PDF