System Operational

EC2 Rightsizing: Stop Paying for Compute You Don't Use

Most AWS accounts run EC2 instances 2-4x larger than needed. AWS Compute Optimizer tells you which ones. Here's how to read the recommendations and act safely.

Dr Salek Ali 19 May 2026
EC2 Rightsizing: Stop Paying for Compute You Don't Use

If you’ve ever opened an AWS bill and wondered where the money went, EC2 is usually the first place to look. It’s not because EC2 is expensive. It’s because most teams provision generously and never go back.

Instances get sized for peak load during a migration, a launch, or a sprint. Then traffic stabilises. The team moves on. The instance stays fat.

AWS Compute Optimizer exists to catch this. It watches your actual usage, runs it through machine learning, and tells you which instances you can downsize without risk, with a specific recommendation for each one.

This post covers how to use it properly, what the numbers actually mean, and how to turn recommendations into real savings without a war story.


What “Rightsizing” Actually Means

Rightsizing is not about running the cheapest possible EC2 instance. It’s about matching instance size to actual workload requirements, with enough headroom to handle peaks without waste.

An oversized instance has two costs:

  1. The direct cost of the unused compute you’re paying for
  2. The indirect cost of never questioning it, because it’s “working fine”

The goal is the right size, not the smallest size.


AWS Compute Optimizer: What It Does

Compute Optimizer analyses CloudWatch metrics for your EC2 instances (CPU utilisation, memory if the CloudWatch agent is installed, network I/O, disk throughput) and compares them against the full AWS instance catalogue.

It then classifies each instance as:

FindingMeaning
Over-provisionedInstance is larger than workload requires
Under-provisionedInstance is too small, performance risk
OptimisedCurrent size is appropriate
Not enough dataLess than 30 days of metrics available

For over-provisioned instances, it gives you up to three alternative instance types with a projected saving and projected performance risk for each.


Enable It in 2 Minutes

Compute Optimizer is free for EC2 (paid tier covers Auto Scaling groups, EBS, Lambda, ECS on Fargate).

To enable it:

AWS Console → Compute Optimizer → Get started → Activate

Or via CLI:

aws compute-optimizer update-enrollment-status \
  --status Active \
  --include-member-accounts \
  --region ap-southeast-2

The --include-member-accounts flag is important if you’re in an AWS Organization. It activates Compute Optimizer across all member accounts, which is where you’ll find the biggest savings.

Give it 24–48 hours on a fresh account. On accounts with existing CloudWatch history, recommendations appear sooner.


Reading Compute Optimizer Recommendations

Navigate to EC2 instances in the Compute Optimizer console. You’ll see a table with columns like this:

  • Instance name/ID
  • Finding (Over-provisioned / Under-provisioned / Optimised)
  • Recommended instance type
  • Projected monthly savings
  • Performance risk (Very low / Low / Medium / High)

Click into any over-provisioned instance and you’ll see the detailed breakdown:

Utilisation Metrics

Compute Optimizer shows the percentile distribution of your usage over the analysis period (typically 14 days):

CPU utilisation:
  P50: 4%
  P90: 11%
  P99: 23%
  Max: 31%

This is the key number. If your P99 CPU is 23% on an instance you’re paying full price for, you have room to move.

Recommendation Options

You’ll get up to three options, ranked by saving:

OptionInstance typeMonthly savingPerformance risk
1m6i.xlarge → m6i.large$87/moVery low
2m6i.xlarge → m7i.large$72/moVery low
3m6i.xlarge → m6a.large$91/moLow

The performance risk rating tells you how confident Compute Optimizer is that the recommended instance won’t constrain your workload. “Very low” is the only one you should action without further investigation. “Medium” and above warrant load testing first.


Memory Metrics: The Gap in Default Recommendations

Here’s something most guides skip: Compute Optimizer cannot see memory utilisation by default.

EC2 doesn’t expose memory metrics to CloudWatch natively. Without memory data, Compute Optimizer is flying partially blind. It might recommend downsizing an instance that’s CPU-light but memory-heavy, and you’d have a problem.

Fix this by installing the CloudWatch agent and configuring memory metric collection:

# Install CloudWatch agent (Amazon Linux 2 / AL2023)
sudo yum install -y amazon-cloudwatch-agent

# Write a minimal config
sudo tee /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json > /dev/null <<EOF
{
  "metrics": {
    "append_dimensions": {
      "InstanceId": "${aws:InstanceId}"
    },
    "metrics_collected": {
      "mem": {
        "measurement": ["mem_used_percent"],
        "metrics_collection_interval": 60
      }
    }
  }
}
EOF

# Start the agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config \
  -m ec2 \
  -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
  -s

Once this is running, Compute Optimizer incorporates memory into its analysis and the recommendations become materially more reliable.

For fleets managed through Systems Manager, deploy via SSM Distributor or use a Launch Template to bake the agent into your AMI.


Acting on Recommendations Without Breaking Production

The recommendation is the easy part. The execution is where teams get nervous.

Here’s a safe process:

Step 1: Filter for “Very Low” Performance Risk Only

Start there. These are the instances where the data strongly supports the downsize. Don’t touch anything rated Medium or above until you’ve done your own analysis.

Step 2: Check the Application Type

Some workloads are inherently spiky: batch jobs, scheduled tasks, CI runners. For these, Compute Optimizer’s percentile-based analysis can miss peaks that matter.

Cross-reference:

  • Does this instance run anything batch or scheduled?
  • Is there a known traffic pattern (e.g. end-of-month processing)?
  • Is it part of an Auto Scaling group? (If yes, resize the Launch Template, not the instance)

Step 3: Resize in Dev/Staging First

If you have a lower environment running the same application, resize there first. Run it for a few days under normal load and monitor.

Step 4: Production Resize Window

For instances in an Auto Scaling group:

  1. Update the Launch Template with the new instance type
  2. Set the group to rolling replacement
  3. Watch CloudWatch metrics during the refresh
  4. Roll back the Launch Template if anything degrades

For standalone instances:

  1. Stop the instance (brief downtime, so schedule accordingly)
  2. Change instance type in the AWS Console or via CLI:
aws ec2 modify-instance-attribute \
  --instance-id i-0abc123def456 \
  --instance-type '{"Value": "m6i.large"}' \
  --region ap-southeast-2
  1. Start the instance and monitor for 15–30 minutes

Step 5: Verify and Document

After the resize, confirm the saving in Cost Explorer and tag the instance with finops:rightsized=true and the date. This closes the loop and creates an audit trail.


What This Actually Costs You in Practice

Let me put some numbers around this.

A typical mid-size AWS account running 20–40 EC2 instances will have 30–50% of those flagged as over-provisioned by Compute Optimizer. The average saving per instance on a “Very low” recommendation is $40–120/month depending on instance family.

For a 30-instance account:

  • 12 instances flagged as over-provisioned (40%)
  • Average saving of $70/month per instance
  • Total monthly saving: $840/month, or $10,000/year

That’s from 12 instance resizes, most of which take 15 minutes each.

The real cost in most organisations isn’t the EC2 bill. It’s the process of no one owning this work. Compute Optimizer tells you exactly what to do, but someone has to have the mandate to actually do it.


Common Mistakes

Resizing based on CPU alone. If memory isn’t being collected, a recommendation might look clean but the instance is actually memory-constrained. Always get the CloudWatch agent in place before acting.

Ignoring instance generation. Moving from m5.xlarge to m6i.large is a generation upgrade AND a size change. The newer generation often performs similarly to the older generation one size up, at a lower price. Compute Optimizer accounts for this. Trust the recommendation, but understand why it’s pointing you at a different generation.

Resizing reserved instances mid-term. If an instance is covered by a Standard Reserved Instance, changing its type breaks the reservation. You’ll lose the RI discount and pay on-demand rates. Check your RI coverage before resizing anything. Convertible RIs give you more flexibility here.

Not setting a review cadence. Rightsizing is not a one-time exercise. Workloads change. New features ship. Traffic patterns evolve. Build a quarterly Compute Optimizer review into your FinOps practice.


Automating the Review (Without Automating the Resize)

You can export Compute Optimizer recommendations to S3 and query them with Athena, or pull them via CLI:

aws compute-optimizer export-ec2-instance-recommendations \
  --s3-destination-config bucket=your-finops-bucket,keyPrefix=compute-optimizer/ \
  --region ap-southeast-2

This gives you a CSV with every recommendation across your account (or org, if you’re running at the management account level).

Use this to build a monthly report that drops into Slack or email: a list of instances, current type, recommended type, and projected saving. Someone reviews it, approves the actions, and the work gets scheduled.

You automate the visibility. Humans approve the changes. That’s the right split.


The Bottom Line

AWS Compute Optimizer is one of the few AWS tools that gives you a specific, actionable recommendation with a dollar figure attached.

Most accounts ignore it because “we’ll get to it” or because no one owns the mandate to touch production. That’s $10K/year sitting in a dashboard nobody checks.

The work is straightforward:

  1. Enable Compute Optimizer across your org
  2. Install the CloudWatch agent for memory metrics
  3. Filter to “Very low” performance risk
  4. Resize one instance at a time, with proper change management
  5. Repeat quarterly

If you want someone to run this across your AWS environment, pull the recommendations, validate them against your workloads, and execute the changes safely, get in touch.