← All Posts
19 February 2026 by Michael
AWSCloudCost Optimisation

AWS cost audits follow a consistent pattern. The bill feels wrong, investigation reveals a pile of waste, and within a week spending drops 20-30%. The fixes are rarely clever. They are things nobody had time to look at.

A mid-size SaaS company spending GBP 11,000 per month on AWS can typically reduce that to around GBP 7,000. Most savings take less than a day to implement.

NAT gateways

This is where the money hides.

NAT gateways appear cheap at around $45 per month each. The real cost is the data processing charge: $0.045 per gigabyte flowing through them. That sounds negligible until CloudWatch reveals private subnets pushing terabytes monthly. Entire compute budgets can be smaller than the NAT gateway line item.

The fix is straightforward. VPC endpoints for the AWS services that private subnets use most, typically S3 and DynamoDB, are free and bypass NAT entirely. Three endpoints can reduce NAT costs by 75% or more. For heavier workloads, a managed NAT instance is significantly cheaper than the gateway, though it adds management overhead.

Forgotten resources

Every AWS account has a graveyard. EC2 instances spun up for a demo and forgotten. Detached EBS volumes. Elastic IPs costing money for doing nothing. Dev databases for cancelled projects quietly running for months at a time.

Cost Explorer sorted by service exposes most of this. The EC2 dashboard sorted by launch date reveals aged instances nobody recognises. Cost Anomaly Detection catches the rest before it accumulates.

Data transfer

Cross-region transfer costs are well understood. What catches teams off guard is that traffic between availability zones in the same region costs roughly GBP 10 per terabyte. Chatty applications with databases in another AZ accumulate charges quickly.

Multi-AZ is essential for production databases. For dev environments, it almost certainly is not.

Over-provisioned instances

Teams size RDS instances for peak load and leave them. A database sitting at 40% CPU most of the week but spiking on Monday mornings pays for a massive instance around the clock.

Compute Optimiser is free. CloudWatch metrics over 90 days reveal consistent under-utilisation. Below 50%? Drop a tier. Scaling back up takes minutes.

S3 storage classes

S3 defaults to Standard storage, and most teams never change it. Data that has not been accessed in 30 days costs significantly less in Infrequent Access. After 90 days, Glacier is cheaper still. For backups and logs that only exist for compliance purposes, Glacier Deep Archive costs a fraction of Standard.

Lifecycle policies automate this entirely. Define rules once and objects move between tiers automatically based on age. A company storing 5TB in Standard that should mostly be in Infrequent Access is overpaying by roughly GBP 50-60 per month. Scale that to 50TB or more and the numbers become meaningful.

The setup takes less than an hour per bucket. The savings compound every month as data accumulates.

CloudWatch log retention

CloudWatch log groups default to “never expire”. Every Lambda invocation, every ECS task, every API Gateway request generates logs that accumulate indefinitely. After a year of operation, the storage costs can rival the services producing the logs.

Most teams need 30 days of logs for debugging and 90 days for audit purposes. Anything beyond that should either be exported to S3 (where lifecycle policies can manage the cost) or deleted. Setting retention policies across all log groups is a one-time job that prevents quiet, permanent cost growth.

EBS snapshots

When EC2 instances get terminated, their EBS snapshots often survive. Automated backup tools create daily snapshots that never get cleaned up. Over months, hundreds of orphaned snapshots accumulate, each costing a small amount that adds up to a surprisingly large line item.

Sort snapshots by creation date in the console. Anything older than the retention period that is not attached to an active backup policy can usually go. Automating snapshot lifecycle with Data Lifecycle Manager prevents the problem from recurring.

Savings plans

Reserved Instances offer slightly better discounts, but Savings Plans are more flexible across instance families and regions. The difference is marginal. A one-year commitment is typically the right balance.

Tagging

Without tagging resources by environment, team, and project, cost conversations are guesswork. It takes an afternoon to set up properly and makes every future spending decision more productive.

Quick audit checklist

For teams that want to work through this systematically:

  • Check NAT gateway data processing charges in Cost Explorer
  • Search for detached EBS volumes, unused Elastic IPs, and aged EC2 instances
  • Review S3 buckets for lifecycle policies and storage class distribution
  • Set CloudWatch log retention on all log groups
  • Sort EBS snapshots by date and remove orphans
  • Run Compute Optimiser and review instance utilisation over 90 days
  • Check for multi-AZ on non-production databases
  • Review Savings Plan coverage for predictable workloads
  • Verify tagging is in place across all resources

Most of these take an afternoon. The savings start immediately.

Most AWS waste is not bad architecture. It is a pile of small things nobody had time to address: NAT gateways processing unnecessary data, forgotten resources ticking away, storage growing unchecked, instances sized for worst cases that never arrive.

If the bill feels too high and the starting point is unclear, get in touch. The big wins usually surface in the first conversation.

Want to talk about this?

If something here is relevant to what you are working on, we are happy to chat.

Get In Touch