Skip to content
← Back to the blog

How to cut AWS costs without sacrificing performance

The five levers we use to cut AWS bills by 30% to 60% at companies that have been in the cloud a while without ever optimising their architecture.

Cover: How to cut AWS costs without sacrificing performance

When we audit a company’s cloud infrastructure for the first time, the same pattern shows up: oversized instances, snapshots piling up since 2021, data sitting in S3 Standard that nobody has touched in two years, and data transfer charges nobody expected to cost that much.

The usual result: between 30% and 60% of the monthly bill can be removed without touching a single line of code or degrading performance.

These are the five levers we apply in every audit.

1. Rightsizing EC2 instances

The most common problem by far. A team spins up an m5.2xlarge to be safe during a traffic spike, the spike passes, and the instance keeps running like that forever.

AWS Cost Explorer has a Rightsizing Recommendations section that analyses CPU and memory usage over the last 14 days. What we almost always find:

  • Instances below 10% CPU usage for 90% of the time
  • Memory utilisation under 30%

The fix is not always to drop down a size. Sometimes the right move is switching from m5 (general purpose) to t3 (burstable), which costs 40% less and handles intermittent workloads perfectly well.

# View rightsizing recommendations with the AWS CLI
aws ce get-rightsizing-recommendation \
  --service EC2 \
  --configuration '{"RecommendationTarget":"SAME_INSTANCE_FAMILY","BenefitsConsidered":true}'

2. Savings Plans and Reserved Instances

If your workloads are stable and predictable, paying on-demand is like renting a car at airport rates every day when you already own one sitting at home.

Compute Savings Plans offer up to 66% off in exchange for committing to a minimum hourly spend over one or three years. They do not tie you to a specific instance type — switch from m5 to m6i and the discount still applies.

The rule we follow: cover your guaranteed baseline consumption with Savings Plans. Everything above that stays on-demand.

3. S3: lifecycle rules and storage classes

S3 Standard costs $0.023/GB/month. S3 Glacier Instant Retrieval costs $0.004/GB/month. If you have data you touch once a month or less, you are paying six times more than you need to.

A simple lifecycle policy we apply by default:

{
  "Rules": [
    {
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER_IR"
        }
      ],
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 30
      }
    }
  ]
}

Old object versions accumulating with no expiration policy is one of the most expensive mistakes, and one of the easiest to fix.

4. Data transfer (the invisible cost)

AWS does not charge for data coming in, but it does charge for data going out. And the rate depends on the destination: region to region, out to the internet, or between availability zones inside the same region.

The one that surprises teams most: traffic between AZs within the same region costs $0.01/GB in each direction. In a microservices architecture with heavy chatter between services in different AZs, that adds up fast.

The usual fixes:

  • Colocate services that talk to each other frequently in the same AZ
  • Use VPC Endpoints so traffic to AWS services (S3, DynamoDB) never leaves for the internet
  • Put CloudFront in front of S3 to cache static content close to the user

5. Orphaned resources

EBS snapshots from instances terminated months ago. Unassigned Elastic IPs (they cost $0.005/hour while idle). Load balancers with zero traffic. Lambda functions with no invocations in 90 days.

None of these is expensive on its own. The problem is that there are usually dozens or hundreds of them piled up.

A basic audit script to find unused EIPs:

aws ec2 describe-addresses \
  --query 'Addresses[?AssociationId==null].[PublicIp,AllocationId]' \
  --output table

The order matters

These levers do not all carry the same impact or the same effort. Our usual sequence:

  1. Orphaned resources — immediate impact, zero risk
  2. S3 lifecycle policies — high impact, 30 minutes to implement
  3. Rightsizing — takes analysis, but usually the biggest saving
  4. Savings Plans — only once the architecture has settled
  5. Data transfer — requires architectural changes, pays off long term

Want to know how much you could save on your current infrastructure? Ask us for an audit. In two weeks you get an executive report with the highest-impact changes, ranked by cost, risk and effort.