Type something to search...

AWS cost diagnosis

Your AWS bill is a number. Fifteen minutes turns it into a list of things to change.

Everything below is done in Cost Explorer, which you already have. No tooling to install, no read-only role to create, no access keys to hand anybody. It will not find everything, and the last section is honest about where it stops.

Start with the check if you want the method. Skip to the second section if the bill has moved and you need to know what caused it.

Can you explain your top three cost drivers?

Four passes over the same data, each one narrowing the question. The output is not a number, it is two or three usage types you can name and go and look at.

  1. 01

    3 min

    Group by Service, three months, monthly

    Open Cost Explorer, set the range to the last three full months at monthly granularity, and group by Service. Write down the top five and what each costs. Most accounts are far more concentrated than people expect — the top three usually carry 70-80% of the bill, and everything below that is not worth your fifteen minutes.

  2. 02

    5 min

    Filter to the top service, group by Usage Type

    This is the step that produces the actual answer, and the one people skip. "EC2" is not a finding. NatGateway-Bytes, EBS:VolumeUsage.gp2 and PublicIPv4:IdleAddress are findings — each names a specific thing you can go and change. Do this for the top two or three services only.

  3. 03

    2 min

    Group by Region

    Spend outside your primary region is almost always unintentional: a test in another region, a service that defaulted somewhere else, a copied Terraform workspace nobody destroyed. It is rarely the largest number on the page, but it is usually the fastest thing to remove because nothing depends on it.

  4. 04

    5 min

    Switch the top usage type to daily

    Same filter, daily granularity. You are looking for the shape. A step change means a deployment or a configuration change, and the date tells you where to look. A gradual ramp means growth, which may be entirely healthy. A flat line that never moves means capacity nobody is using.

The bill went up. Check these five first.

Traffic growth is the assumption and it is usually wrong, or at least incomplete. Step four above gives you a date. These are the five things that tend to be sitting on it, in the order they are worth checking.

A deployment A step change on a specific date
Correlate the date from step four against your deploy history. An instance class bumped for a load test, a replica count raised, a cache added — the change is usually deliberate and the failure is that nobody reverted it.
A logging change CloudWatch rising independently of traffic
Log level moved to DEBUG and stayed there, a new subsystem started emitting per-request logs, or retention was extended. CloudWatch bills you on ingestion, so this shows up immediately and keeps billing every month afterwards.
Network path changes NatGateway-Bytes or cross-AZ transfer climbing
A workload that used to reach S3 or DynamoDB over a gateway endpoint now goes out through the NAT gateway, or services that used to sit in one availability zone now talk across two. Neither change looks like a cost change when it is made.
A new region Spend appearing in a region you do not run in
Someone evaluated a service elsewhere, or a stack was deployed to a default region. The spend is often small per line but permanent, and it never appears in a service-level view because it is spread across several services.
A scaling event that never unwound A step change with no corresponding step back down
Autoscaling minimums raised during an incident, an RDS instance class increased to get through a migration, provisioned capacity set for a launch. The scale-up is remembered; the scale-down is not.

Five charges that do not announce themselves

These are not obscure services. They are ordinary parts of a normal architecture that bill in a way people do not expect, which is why they survive several rounds of cost review.

Charge Usage type Rate Why it hides
NAT gateway NatGateway-Hours, NatGateway-Bytes $0.045/hr + $0.045/GB Billed per gateway per hour and again on every gigabyte through it. A gateway in each of three availability zones is three hourly charges before any traffic moves. Traffic to S3 and DynamoDB routed through it is paying twice for something a gateway endpoint does at no charge.
Cross-AZ data transfer DataTransfer-Regional-Bytes $0.01/GB each direction Charged in both directions, so a round trip between two services in different availability zones costs twice the figure you remember. Chatty internal traffic is the usual source, and it appears under EC2 rather than under anything that sounds like networking.
CloudWatch log ingestion DataProcessing-Bytes ~$0.50/GB ingested The cost is in ingestion, not storage, which inverts the intuition most people bring to it. Reducing retention on existing logs saves comparatively little. Reducing what is emitted saves a great deal.
Idle compute BoxUsage:*, Fargate-vCPU-Hours Full on-demand rate, continuously Development and staging environments running through nights and weekends cost the same per hour as production. So do load balancers left behind by deleted services, and instances kept for a migration that finished.
Idle storage and old volume types EBS:VolumeUsage.gp2, EBS:SnapshotUsage, PublicIPv4:IdleAddress gp2 $0.10 vs gp3 $0.08 per GB-month Unattached volumes bill at the same rate as attached ones. Snapshot chains accumulate silently. gp2 volumes cost about a fifth more than gp3 for the same performance, and the conversion is an in-place modification with no downtime.

Rates are us-east-1 on-demand list prices and are indicative. Your region and any commitments you hold will change them.

Where this check stops

Cost Explorer reports what you were billed. It does not know utilisation, so it cannot tell you that an instance is running at four percent CPU, and it cannot tell you which of two workloads sharing a usage type is the one worth changing.

And if most of your bill turns out to be model inference rather than the infrastructure around it, this is the wrong tool for the job — attributing spend per feature and per user is a different exercise.

It will also not tell you which of the changes you have just found are safe to make. That is usually the reason a list like this sits unactioned for months — not that the waste is hard to see, but that nobody is confident enough about production to touch it.

Get the change list

Two Cost Explorer exports, a change list you approve before anything is touched, and a fee of one month of the verified reduction.