The problem
The monthly AWS bill had grown quarter over quarter until finance asked engineering a question nobody could answer: what are we actually paying for? Costs weren't attributed to teams or services, environments ran 24/7 regardless of use, and every workload sat on on-demand instances sized by optimism.
The approach
Visibility before cuts. Kubecost was deployed to attribute Kubernetes spend to namespaces, teams, and services; AWS cost allocation tags did the same for everything outside the cluster. You cannot optimise what you cannot see — the first month produced no savings, just an honest map.
Right-sizing with data. With real utilisation numbers, we resized the chronically over-provisioned: requests/limits tuned from actual usage percentiles, instance families corrected, storage classes matched to access patterns.
Spot where it's safe. Stateless, interruption-tolerant workloads (CI runners, batch jobs, most of the web tier behind a load balancer) moved to Spot instances with diversified instance pools and graceful-termination handling. Savings Plans covered the steady-state baseline.
Kill the zombies. Non-production environments got automatic evenings-and-weekends shutdown. Unattached volumes, idle load balancers, and forgotten snapshots were reaped on a schedule, not in an annual cleanup.
Make it stick. Cost per team went on a monthly dashboard reviewed alongside reliability metrics. Optimisation became a habit with an owner, not a one-off project.
The outcome
- Monthly AWS spend down 42% with zero reduction in capacity available to
production traffic.
- Every rupee of spend attributable to a team and a service.
- Spot + Savings Plans coverage keeps the structural rate low even as usage
grows.
- The savings paid for the engagement many times over in the first quarter.