AWS cost optimisation is rarely about finding one dramatic saving — it is a handful of unglamorous, recurring practices: rightsizing compute, matching purchase commitments to actual usage, and cleaning up the storage and data-transfer waste that accumulates silently. Most accounts that haven't had a deliberate cost review can cut 20-30% without touching application architecture, just from the categories below.
Rightsizing compute with actual utilisation data
The most common waste is EC2 and RDS instances provisioned for a peak load that rarely happens, running at 10-20% average CPU utilisation year-round. AWS Compute Optimizer analyses CloudWatch metrics and recommends a smaller instance type or family change based on actual usage, not guesswork — running it across an account with no prior rightsizing effort routinely surfaces double-digit percentage savings. Pair rightsizing with a review of instance generation: a newer generation (e.g. moving from M5 to M7i) is often both cheaper per unit of compute and faster.
# Find EC2 instances with low average CPU over the last 14 days
aws ce get-rightsizing-recommendation \
--service "AmazonEC2" \
--configuration '{"RecommendationTarget":"SAME_INSTANCE_FAMILY","BenefitsConsidered":true}' \
--query 'RightsizingRecommendations[].{Instance:CurrentInstance.ResourceId,Rec:ModifyRecommendationDetail.TargetInstances[0].ResourceDetails}'
Reserved Instances, Savings Plans, and Spot
On-demand pricing is the most expensive way to run steady-state workloads. Compute Savings Plans give a discount (typically 20-40% versus on-demand) in exchange for a 1- or 3-year commitment to a dollar amount of compute spend, and are more flexible than Reserved Instances since they apply across instance families and even to Fargate/Lambda. For workloads that tolerate interruption — batch jobs, CI runners, stateless worker fleets — Spot Instances add another 60-90% discount on top, provided the workload is checkpointed or naturally retryable.
Look at 3-6 months of stable usage before committing to a 1- or 3-year Savings Plan. Committing during a temporary usage spike locks in a payment obligation for capacity you may not keep using, which turns a savings mechanism into a fixed cost you're stuck with.
S3 storage tiering and lifecycle rules
S3 storage costs creep because objects default to Standard storage forever unless a lifecycle rule moves them. S3 Intelligent-Tiering automatically shifts objects between access tiers based on actual access patterns and has no retrieval fee, making it the safe default for buckets with unpredictable access. For buckets with predictable aging (logs, backups), explicit lifecycle rules transitioning to Glacier or Glacier Deep Archive after a set number of days are cheaper still, since you're not paying the small monitoring fee Intelligent-Tiering charges per object.
Data transfer and NAT Gateway costs
Cross-AZ and cross-region data transfer, plus NAT Gateway hourly and per-GB charges, are the cost category most teams underestimate because it doesn't show up as a line item tied to an obviously named resource. A NAT Gateway processing significant egress traffic can cost more per month than the EC2 instances behind it. VPC endpoints for S3 and DynamoDB (which route traffic privately without touching the NAT Gateway) are a near-zero-effort fix that eliminates NAT charges for traffic to those services specifically.
Without consistent resource tagging (team, environment, project), Cost Explorer and Cost and Usage Reports can show total spend but not who owns it. Enforce tagging via AWS Config rules or Service Control Policies before trying to optimise — you cannot fix what you cannot attribute to an owner.
Unused and orphaned resources
Unattached EBS volumes, idle Elastic IPs, old EBS snapshots past their retention need, and load balancers with zero registered targets are pure waste that accumulates from normal operational churn — someone terminates an instance and forgets the volume, or decommissions a service and leaves the ALB running. AWS Trusted Advisor's cost optimisation checks (available on Business/Enterprise support) surface most of these automatically; on lower support tiers, a scheduled script against the relevant APIs does the same job.
| Category | Typical saving |
|---|---|
| Rightsizing (Compute Optimizer) | 10-30% of compute spend |
| Savings Plans on stable baseline | 20-40% versus on-demand |
| Spot for interruptible workloads | 60-90% versus on-demand |
| S3 Intelligent-Tiering / lifecycle rules | Varies, often 20%+ of storage spend |
| VPC endpoints (skip NAT for AWS traffic) | Eliminates NAT charges for that traffic |
Wrapping up
Cost optimisation on AWS is a recurring practice, not a one-time project — usage patterns shift, new services get spun up, and old resources linger. Start with rightsizing and tagging since both compound the value of everything after them, add Savings Plans once usage is stable enough to commit against, and put a scheduled check in place for orphaned resources so the cleanup doesn't have to happen manually every quarter.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.