Where the money usually goes
AWS bills leak in predictable places. Once you can read the bill (the previous lesson), you go looking for waste — and there is a well-known catalogue of it, the same culprits in almost every account. Knowing this list means you can find and cut real money quickly, because most AWS waste falls into a handful of categories. This lesson is where the money usually goes, and how to stop it.
Idle and forgotten resources
The biggest category is resources that are running (and billing) but not doing useful work:
- Unattached EBS volumes. When an instance is terminated, its extra EBS volumes can be left behind, unattached — and you keep paying for the storage. Orphaned volumes accumulate silently. Find and delete unattached volumes (after checking they hold nothing needed).
- Old EBS snapshots and AMIs. Snapshots pile up from backups and are rarely cleaned; each costs storage. Set a retention policy and delete old ones.
- Idle load balancers. A load balancer with no healthy targets, or serving a decommissioned service, still charges its hourly fee. Find load balancers with no traffic and remove them.
- Unused Elastic IPs. An Elastic IP that is allocated but not attached to a running instance is charged (AWS bills for idle Elastic IPs specifically). Release ones you are not using.
- Stopped instances still costing storage. A stopped EC2 instance is not charged for compute, but its EBS volumes still cost — a "stopped to save money" instance still bills for storage.
- Old environments never torn down. A test or demo environment spun up and forgotten runs forever. Tag environments (billing-setup) and tear down what is no longer used.
These idle resources are pure waste — money for nothing — and they are the fastest win: a sweep for unattached volumes, unused Elastic IPs, idle load balancers and forgotten environments usually finds real, immediate savings. This is exactly the kind of cleanup a regular cost review (the cost-review lesson) catches.
Over-provisioning
The second big category is resources that are bigger than they need to be — paying for capacity that sits idle:
- Over-sized instances. An instance averaging 10% CPU is several sizes too big; you pay for CPU and memory you never use (the rightsizing lesson goes deep). Right-size to actual usage.
- Over-provisioned databases. An RDS instance far larger than the workload needs, or with more storage/IOPS than used.
- Excessive replicas or capacity headroom. Running far more instances/pods than the load requires "to be safe" — pay for peak capacity that rarely arrives, when autoscaling (the scaling lesson) would add it only when needed.
Over-provisioning is the single largest source of ongoing waste because it is so common — teams size for a worst case, never revisit it, and pay the margin forever. Right-sizing (the next lesson) addresses this directly.
Data transfer: the sneaky one
Data transfer is the waste people least expect, because it is not a resource you see running:
- Data out to the internet is charged per GB — a chatty API, large downloads, or serving lots of media directly from your servers can run up real costs.
- Cross-AZ traffic is charged — an architecture that sends a lot of traffic between Availability Zones (a chatty service talking to a database in another AZ) pays for it. Keeping traffic within an AZ where sensible reduces this.
- NAT gateway data processing (the gateways lesson) — every GB from private subnets to the internet through NAT is charged; heavy outbound (large image pulls, external API calls) through NAT adds up. VPC endpoints (the private-connectivity lesson) keep AWS-service traffic off NAT, cutting this.
- Cross-region transfer is charged and often higher — replicating or moving data between regions can be surprisingly expensive.
Data transfer waste is diagnosed by reading the bill (it appears as data-transfer line items) and reduced by architecture: VPC endpoints for AWS services, keeping chatty traffic within an AZ, using a CDN (CloudFront) for internet-facing content rather than serving it from your servers, and avoiding unnecessary cross-region movement. It is worth checking precisely because it is invisible until you look at the bill.
Not using the discounts you could
The final category is not waste exactly, but money left on the table — paying more than necessary for the same usage:
- On-demand pricing for steady workloads that could be on Savings Plans or Reserved Instances (the next lesson) — a large discount for committing to baseline usage you are running anyway.
- x86 instead of Graviton — ~20% more for equivalent compute (the compute module).
- On-demand instead of Spot for interruptible, replicated workloads — up to ~90% more (the compute module).
- No lifecycle policies on ECR images (the building-images lesson) or CloudWatch log retention (the logs lesson) — storage growing forever.
Applying the discounts and levers you are entitled to — Savings Plans for the baseline, Graviton by default, Spot for the interruptible, retention policies on storage — cuts the same workload's cost substantially without changing what you run.
The waste-hunting habit
Put together, finding waste is a systematic sweep of these categories: idle/forgotten resources (delete them), over-provisioning (right-size), data transfer (fix the architecture), and unused discounts (apply them). Most of an account's waste is in this list, so a periodic pass through it — in the cost review (the cost-review lesson) — reliably finds savings. The mindset is that waste is normal and expected in a growing account, not a sign of failure, and the job is to sweep for it regularly and cut it — the same "deliberate, ongoing attention" that this course applies to reliability, security and everything else.
Check your work
Idle/forgotten (fastest win): unattached EBS volumes, old snapshots/AMIs, idle load balancers, unused Elastic IPs (charged when unattached), stopped instances' EBS storage, forgotten environments. Pure waste — sweep and delete.
Over-provisioning (largest ongoing): over-sized instances (10% CPU = too big), over-provisioned databases, excessive replicas/headroom (autoscale instead of paying for peak). Right-size (next lesson).
Data transfer (the sneaky one): out-to-internet per GB, cross-AZ, NAT data processing (use VPC endpoints), cross-region. Diagnosed by reading the bill; reduced by architecture (endpoints, keep traffic in-AZ, CDN, avoid cross-region).
Unused discounts (money on the table): on-demand for steady workloads (→ Savings Plans/RIs), x86 (→ Graviton), on-demand for interruptible (→ Spot), no lifecycle/retention (storage grows forever). Apply the levers.
Habit: systematic sweep of these categories in the cost review; waste is normal in a growing account — sweep regularly and cut.
Practice
- List the common idle/forgotten resources and how you'd find and remove each.
- Explain why over-provisioning is the largest source of ongoing waste and how autoscaling helps.
- Explain the three kinds of data-transfer cost and an architectural fix for each.
- Explain why data-transfer waste is "invisible until you read the bill."
- List the discounts/levers commonly left unused and roughly what each saves.
- Describe a systematic sweep you would run to find waste in an AWS account.
Official documentation
- AWS — Well-Architected cost optimisation pillar — Where cost accumulates and how to reduce it.
- AWS — Data transfer costs — Understanding transfer charges.
- AWS — Cost optimisation best practices — Finding and removing waste.
Next: right-sizing and scale-to-zero for non-production.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship