The uncomfortable truth
Most startups are overspending on AWS by 30–50%. Not because AWS is expensive — because infrastructure decisions made in the first few weeks of a project tend to stick around forever, even when the reasons for them have long since changed.
We've audited dozens of AWS environments. The same patterns come up every time.
The big wins
1. Right-size your compute
This is the single biggest cost savings available to most startups. You provisioned an m5.xlarge because you weren't sure what you'd need. Six months later, your average CPU utilisation is 12%.
What to do: Check CloudWatch metrics for the last 30 days. If average CPU is below 40%, you're over-provisioned. Drop down one instance size. If you're running multiple instances behind a load balancer, consider reducing the count before reducing the size.
Typical savings: 30–50% of your EC2 bill.
2. Use Reserved Instances or Savings Plans
If you've been running the same instance types for three months and plan to continue, you're leaving money on the table by paying on-demand prices.
What to do: For stable workloads, commit to 1-year Savings Plans. You'll save 30–40% compared to on-demand pricing with no upfront payment required.
Typical savings: 30–40% of committed compute spend.
3. Review your data transfer
Data transfer costs are the hidden killer in AWS bills. Inter-AZ transfer, NAT Gateway charges, and CloudFront costs add up quickly.
What to do:
- Keep services that talk to each other in the same AZ when possible
- Use VPC endpoints for S3 and DynamoDB instead of routing through NAT Gateways
- Review your CloudFront distribution — are you caching effectively?
Typical savings: 10–25% of your networking costs.
4. Clean up what you're not using
Unattached EBS volumes. Old snapshots. Unused Elastic IPs. Idle load balancers. Forgotten development environments that run 24/7.
What to do: Run AWS Cost Explorer's "idle resources" report. Set up a weekly Slack alert for resources with zero traffic. Tag everything with an environment label and auto-stop development resources outside business hours.
Typical savings: Usually 5–15% of total bill, but it compounds.
The medium wins
5. Database right-sizing
RDS instances are often over-provisioned. Check your database's CPU and memory utilisation. If you're running a db.r5.xlarge and your peak memory usage is 4GB, you can probably drop to a db.r5.large.
Also consider: do you need Multi-AZ for your development database? Probably not. That's a 2x cost reduction right there.
6. S3 lifecycle policies
If you're storing user uploads, logs, or backups in S3 Standard, you're overpaying for data that's rarely accessed. Set up lifecycle policies to move objects to S3 Infrequent Access after 30 days and Glacier after 90 days.
7. Lambda optimisation
If you're using Lambda, check your memory settings. Lambda pricing scales linearly with memory, but execution time often drops as memory increases. The sweet spot is usually where cost = memory × time is minimised — and that's rarely the default 128MB.
The system fix
Individual optimisations help, but the real fix is making cost visibility a habit:
- Tag everything — by environment, team, and service
- Set up weekly cost reports — delivered to Slack or email
- Set budget alerts — at 80% and 100% of expected monthly spend
- Review quarterly — infrastructure needs change as your product evolves
The goal isn't to spend as little as possible. It's to spend intentionally — knowing exactly what you're paying for and why.