A 40% jump on the invoice and nobody changed anything. Except somebody did — or something expired, replicated, or quietly kept accumulating. Sudden AWS cost increases are rarely mysterious. They come from a short list of causes, and each one leaves a specific fingerprint in Cost Explorer or the Cost and Usage Report (CUR). Here are the eight we'd check first, and where each one shows up.
First: find the day the line bent
Before hunting suspects, open Cost Explorer, set granularity to daily, set the range to the last three months, and group by Service. A sudden increase is a step change, not a slope — the date it starts narrows every question that follows. Once you have the date and the service, regroup by Usage Type. Most of the checks below are one more group-by from there.
1. Resources left behind from a finished project
The migration ended. The proof of concept got approved. The resources stayed. Unattached EBS volumes bill per GB-month whether anything uses them. Every public IPv4 address bills hourly now, attached or idle. Load balancers bill hourly with zero targets. A stopped RDS instance still bills storage — and AWS restarts it after seven days, so compute charges come back on their own.
- Where to look: Cost Explorer grouped by Usage Type. Volume usage lands under EC2-Other; load balancer hours show up under EC2-ELB; public IPv4 charges appear under Amazon VPC. In the CUR (with resource IDs enabled), `line_item_resource_id` names the exact volume or address so you can trace the owner.
2. Data transfer and NAT processing
NAT Gateway charges a per-GB processing fee on every byte that flows through it, on top of the hourly rate. A workload that starts pulling S3 objects — including ECR image layers — through a NAT Gateway instead of a free S3 gateway endpoint turns a networking detail into a line item. Cross-AZ traffic bills per GB in each direction, so a chatty service split across zones pays twice.
- Where to look: group by Usage Type under EC2-Other and search for `NatGateway-Bytes` and anything containing `DataTransfer`. If NAT bytes dominate, VPC Flow Logs will tell you which ENI is doing the talking.
3. Snapshot and log accumulation
Storage that grows forever doesn't spike — it compounds until someone notices. EBS snapshots with no Data Lifecycle Manager policy accumulate per GB-month indefinitely. CloudWatch log groups default to never expire, and ingestion charges alone can outrun the storage.
- Where to look: usage types containing `SnapshotUsage` (EBS) and `TimedStorage-ByteHrs` (CloudWatch and S3). In the CloudWatch console, sort log groups by stored bytes and check retention settings — "Never expire" on a debug-level group is the usual culprit.
4. Commitment coverage expired
The workload didn't change at all. The one-year Savings Plan or Reserved Instances did — they lapsed, and the same usage started billing at on-demand rates. This is the classic "usage flat, cost up" spike.
- Where to look: Cost Explorer's Savings Plans and Reservations coverage reports. A coverage percentage that falls off a cliff on the spike date is the answer. Check the inventory pages for expiration dates before the next one lands.
5. Someone raised the autoscaling floor
During an incident, minimum capacity gets bumped from 2 to 8. The incident ends; the minimum doesn't. Scheduled scaling set for a launch stays at launch levels. ECS desired counts creep up. The result is a permanent step up in running hours.
- Where to look: Cost Explorer grouped by Instance Type at daily granularity — running hours step up on a specific day. Then search CloudTrail for `UpdateAutoScalingGroup` and ECS `UpdateService` events around that date to find who and why.
6. New-region duplication
A DR test, S3 Cross-Region Replication, DynamoDB global tables, or copied AMIs put a second copy of your data in another region. Now you pay storage twice plus inter-region transfer per GB for every replicated write.
- Where to look: group by Region. A region that billed near zero last quarter and real money this quarter is the tell. Then group that region by Service to see whether it's storage, replication traffic, or full compute duplication.
7. GPU and AI experiments left running
A single GPU instance from the p or g families can cost more per hour than a rack of general-purpose instances. SageMaker real-time endpoints bill per instance-hour while deployed — zero invocations doesn't mean zero cost. Bedrock provisioned throughput bills hourly whether or not anything calls the model.
- Where to look: group by Service and check SageMaker and Bedrock directly; group by Instance Type and scan for g- and p-family names. Anything GPU-shaped that runs nights and weekends deserves a hard question.
8. Storage class drift
Data that was supposed to move to Infrequent Access or Glacier is sitting in S3 Standard because the lifecycle rule was never applied — or filters on a prefix that no longer matches. Versioned buckets keep every noncurrent version at full storage rates until a rule expires them. Incomplete multipart uploads hold storage invisibly until a cleanup rule aborts them.
- Where to look: Cost Explorer usage types show `TimedStorage` broken out by storage class — watch the Standard line versus the rest. S3 Storage Lens shows per-bucket growth, noncurrent version bytes, and incomplete multipart bytes without writing a single query.
The pattern
Every suspect above falls to the same three moves: daily granularity to find the date, group by Service to find the neighborhood, group by Usage Type to find the mechanism. When Cost Explorer runs out of resolution, the CUR's resource IDs finish the job. None of this requires write access to anything — which is exactly how we do it.
If the spike is on this month's bill and you want it traced to specific resources, our fixed-price AWS cost review starts at $4,500 and runs entirely on read-only access.