Someone runs a load test on Friday afternoon against a fleet of GPU instances and forgets to tear it down. You find out on the 3rd of the following month, when the invoice arrives with an extra $2,400 on it. Nothing was broken, nobody did anything reckless, and the mistake was recoverable for the first hour — you just had no way to know about it until AWS told you, three weeks later, in a PDF.
That gap is what AWS Cost Anomaly Detection exists to close. It's free, it takes about ten minutes to configure, and it should be on in every AWS account. It's also narrower than most people assume when they turn it on, so this post covers both halves: how to set it up properly, and which category of spend it will never say a word about.
What is AWS Cost Anomaly Detection?
It's a feature inside AWS Billing and Cost Management that runs machine-learning models over your Cost Explorer data, learns what each of your services normally costs, and alerts you when spend deviates from that pattern.
Two pieces of vocabulary matter, because the console makes you create both:
- A monitor defines what is watched. The one you want is an AWS services monitor, which evaluates every service in your account separately — so a spike in Amazon SageMaker gets noticed even if your total bill barely moves. You can also monitor a specific linked account, a cost category, or a cost allocation tag.
- An alert subscription defines who hears about it and when — the recipients, and the threshold an anomaly must clear before it's worth interrupting anyone.
The detection itself is comparative, not absolute. There is no dollar figure that is "too high" in the abstract; there's only spend that doesn't match your own history. That's the source of both its strength and its blind spot.
Is AWS Cost Anomaly Detection free?
Yes. The feature itself carries no charge, however many monitors and subscriptions you create. If you route alerts through an SNS topic rather than plain email you'll pay standard SNS rates, which for this volume of messages rounds to nothing.
Since it's free and read-only, there is no real argument for leaving it off. The only cost is attention — which is why the threshold you pick matters more than anything else in the setup.
How do I set it up?
Check whether it's already running before you build anything. Since March 2023 AWS automatically configures a default services monitor for new Cost Explorer users, so plenty of accounts already have detection switched on — with nobody subscribed to the alerts, which is the half that matters.
In the console: Billing and Cost Management → Cost Anomaly Detection → Cost monitors → Create monitor. Choose AWS services, name it, and on the next screen attach an alert subscription with recipients and a threshold.
Pick your alert frequency deliberately, because it determines the delivery channel as well as the noise level:
| Frequency | Delivery | Best for |
|---|---|---|
| Individual alerts | As detected — requires an SNS topic | Production accounts where a spike needs same-day action |
| Daily summaries | Email; top 10 anomalies from the previous day, generated 00:00 UTC | Most teams — enough speed, far less noise |
| Weekly summaries | Email; one digest per week | Low-spend or dormant accounts |
The email options need at least one email recipient and can't publish to SNS, so if you want anomalies in a chat channel, individual alerts is the only frequency that gets you there.
The same thing from the CLI, which is easier to roll out across several accounts:
# 1. A monitor that evaluates every AWS service independently
aws ce create-anomaly-monitor --anomaly-monitor '{
"MonitorName": "services-monitor",
"MonitorType": "DIMENSIONAL",
"MonitorDimension": "SERVICE"
}'
# 2. A daily digest for anomalies with at least $100 of total impact
aws ce create-anomaly-subscription --anomaly-subscription '{
"SubscriptionName": "daily-cost-anomalies",
"MonitorArnList": ["arn:aws:ce::123456789012:anomalymonitor/EXAMPLE"],
"Subscribers": [{ "Type": "EMAIL", "Address": "platform@example.com" }],
"Frequency": "DAILY",
"ThresholdExpression": {
"Dimensions": {
"Key": "ANOMALY_TOTAL_IMPACT_ABSOLUTE",
"MatchOptions": ["GREATER_THAN_OR_EQUAL"],
"Values": ["100"]
}
}
}'
If you run AWS Organizations, create the monitor in the management account — it then covers every linked account, and you can add per-account monitors for the teams that want their own alerts. Doing it the other way round, account by account, means the first thing anyone does with a new account is forget this step.
Set it too low and you'll get an alert every time a batch job runs on a Tuesday; within a month everyone has filtered the emails into a folder nobody opens, and the alert that actually mattered dies there with the rest. Set it too high and the $300 mistakes never surface. Start around $100 of absolute impact for a small account, then tune it after a few weeks against what actually landed — the goal is a signal your team still reads in six months.
How do I get anomaly alerts into Slack?
Email subscriptions are the fastest path, but an alert nobody sees on a Saturday isn't much use. To route anomalies into a channel, create an individual alerts subscription pointed at an SNS topic, then map that topic to a Slack channel with Amazon Q Developer in chat applications — the service formerly called AWS Chatbot.
Two things quietly break this, both worth checking the day you set it up. The SNS topic's access policy has to allow the costalerts.amazonaws.com service principal to publish to it:
{
"Sid": "AWSAnomalyDetectionSNSPublishingPermissions",
"Effect": "Allow",
"Principal": { "Service": "costalerts.amazonaws.com" },
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:us-east-1:123456789012:cost-anomalies"
}
And the topic subscription itself has to be confirmed — if it's still sitting at PendingConfirmation in the SNS console, nothing is delivered and nothing tells you so. If the topic is encrypted with a KMS key, that key's policy needs to grant the same principal kms:GenerateDataKey* and kms:Decrypt.
What does it actually catch — and what does it miss?
It catches change. A step function in spend: the forgotten load test, a runaway Lambda retry loop, a misconfigured data pipeline scanning your whole S3 bucket every five minutes, a new region someone spun up by accident. For that entire category it is genuinely excellent, and it's the reason to turn it on today.
What it structurally cannot catch is steady-state waste, and that's the larger number on most bills.
Think about what "anomaly" means here. The model is trained on your own history, so anything that has been billing consistently is your baseline. An idle load balancer that has quietly charged ~$22/month since last year isn't an anomaly — it's the most normal thing in your account. Neither is the unattached EBS volume, the Elastic IP nobody released, the S3 bucket where everything sits in Standard, or the over-provisioned RDS instance that's been twice the size it needs since launch. Waste that arrives gradually — one preview environment at a time — never produces the step change the detector is looking for. It just becomes the new normal, one small increment at a time.
There are three narrower limitations worth knowing too:
- It's retrospective. Cost data lands roughly a day late, so the earliest an alert can reach you is usually the day after the spend happened. That's twenty-something days better than the invoice, but it's not prevention.
- Root-cause attribution is coarse. You get the service, region, usage type, and account. Which resource is on you to find.
- It needs history. A brand-new account or a newly-added service has nothing to be abnormal against, so the first stretch is quiet by definition.
None of this is a criticism of the service — a spike detector doing spike detection is working correctly. The mistake is treating it as cost coverage. Anomaly detection tells you when something changed; it can't tell you that what you've been running all along was never needed.
What should I pair it with?
Three things, in rough order of effort:
- AWS Budgets, for the complementary signal. Budgets alert on forecast and on thresholds you choose — "we're on track to exceed $5,000 this month" — which catches the slow drift anomaly detection ignores. Budgets that only monitor and notify are free; you only start paying if you attach automated actions to them.
- A recurring waste audit. Anomaly detection covers new spend; nothing in the AWS console covers old spend that stopped being useful. Our checklist for cutting an AWS bill is one you can work through in an afternoon, ordered by savings-per-minute. CloudWatch is the textbook case of what a spike detector misses — see why is CloudWatch so expensive? for a line item that grows a few percent a month until it is one of the largest on the bill. Orphaned storage is the other classic blind spot: a nightly snapshot job with no retention adds a few gigabytes a day forever, which is a perfectly smooth curve to a spike detector and a real number by the end of the year — finding and deleting orphaned EBS volumes and snapshots covers that one.
- Ownership tags. When an alert does fire,
owneris the tag that turns a two-day investigation into a Slack message.
Together those cover the two failure modes: something new went wrong, and something old was never right.
How do I cover both at once?
This is the split Parsivex is built around. Daily anomaly checks compare each service's spend against the median of its trailing 14 days, and only raise an alert when the jump clears both a ratio and an absolute dollar floor — so a tiny service doubling from $0.50 to $1.00 a day stays quiet, and a real spike doesn't. Alongside that, scheduled scans check every region for the 26 kinds of steady-state waste no anomaly model will ever flag, because by the time the model sees them they're already the baseline.
For how the daily checks, baselines, and severity thresholds work in detail, see cost anomaly alerts — including which plans include them — or how scans work for what a scan reads from your account.