Built a Cost Spike Alert System After AWS Charged Me $800 for a Forgotten EC2 Instance
Jenkins
Source: Dev.to | Dec 26, 2025 (UTC)
So there I was, checking my AWS bill like I do every month, and boom – $800 more than expected. Turns out I left a beefy EC2 instance running in ap-south-1 after a client demo three weeks ago. Classic mistake. We’ve all done it.
That night I decided enough was enough. I needed something that would ping me the moment costs started looking weird, not after the damage was done.
Here’s what I built and how you can set it up too.
The Problem with Regular Budget Alerts
AWS Budgets exists, yeah. But here’s the thing – it only tells you when you’ve crossed a line you drew yourself. If I set a $500 budget and I hit $499, silence. Hit $501, alert. But what if my normal spend is $200 and suddenly it jumps to $400? That’s a 100% increase and Budgets won’t say a word because I’m still “under budget.”
What I needed was something smarter. Something that knows what normal looks like and yells when things go sideways.
Enter Cost Anomaly Detection
AWS has this service called Cost Anomaly Detection that does exactly this. It uses ML to figure out your spending patterns and alerts you when something breaks the pattern. And get this – it’s free. No extra charges for the detection itself.
Let me walk you through setting this up.
Part 1: Basic Setup (10 minutes) Go to Billing Console > Cost Anomaly Detection. If you created your AWS account recently, there might already be a default monitor there. Click Create monitor and pick AWS Services as the type. This watches all your services together. Name it something useful – I called mine all-services-prod.
Now create an alert subscription:
Name: daily-cost-alerts
Frequency: Individual alerts (I want to know immediately)
Threshold: $50 (adjust this based on your typical spend)
For notification, you have two options:
Direct email – simple, works fine
SNS topic – more flexible, what I recommend
I chose SNS because I wanted to send alerts to Slack and also format the messages eventually.
Part 2: Setting Up SNS
Head to SNS Console and create a standard topic. I named mine cost-alerts. Add your email as a subscriber. You’ll get a confirmation email – click the link or nothing will work. I’ve forgotten this step more times than I’d like to admit. Go back to Cost Anomaly Detection and update your subscription to use this SNS topic. At this point, you’ve got a working system. AWS will detect weird spending and email you. Done. But the emails look terrible. Just a blob of JSON. So I added a Lambda function to make them readable.
Now you need to wire it up. Create another SNS topic called cost-anomaly-raw. Set your Lambda as a subscriber to this topic. Then update Cost Anomaly Detection to send to cost-anomaly-raw instead of directly to cost-alerts.
The flow is now: Anomaly detected → cost-anomaly-raw → Lambda formats it → cost-alerts → Your email
Part 4: Catching Expensive Stuff in Real-Time
Here’s the thing about Cost Anomaly Detection – it relies on billing data, which can be delayed by hours. If someone spins up a p4d.24xlarge (those GPU monsters that cost $30+/hour), I don’t want to find out 6 hours later. EventBridge lets us catch these events as they happen.
import boto3 import os sns = boto3.client('sns') ec2 = boto3.client('ec2') # Instance types that'll wreck your budget EXPENSIVE = ['p4d', 'p3', 'p2', 'x2', 'u-', 'dl1', 'inf1', 'g5', 'g4dn'] def lambda_handler(event, context): instance_id = event['detail']['instance-id'] resp = ec2.describe_instances(InstanceIds=[instance_id]) instance_type = resp['Reservations'][0]['Instances'][0]['InstanceType'] # Check if it's something expensive if any(e in instance_type for e in EXPENSIVE): msg = f"Heads up: {instance_type} just launched\n" msg += f"Instance: {instance_id}\n" msg += f"Region: {event['region']}\n" msg += f"\nThese instances are expensive. Make sure this was intentional." sns.publish( TopicArn=os.environ['ALERT_TOPIC'], Subject=f'Expensive EC2 launched: {instance_type}', Message=msg ) return {'statusCode': 200}
Enter fullscreen mode
Exit fullscreen mode
Now you get pinged within seconds when someone launches a GPU instance or any other budget-killer.
What This Actually Catches
After running this for about two months, here’s what it’s caught for me:
A Lambda function that got stuck in a retry loop (spotted within 2 hours instead of end of month)
Teammate who launched m5.4xlarge instead of t3.medium for testing
Unexpected data transfer spike when a client started hammering our API
S3 request costs jumping 3x after a deployment (turned out we had a logging misconfiguration)
Few Things I Learned
Start with a higher threshold. I initially set $20 and got way too many alerts for normal fluctuations. Bumped it to $50 and the noise dropped significantly.
The ML needs time. Cost Anomaly Detection takes about 10 days to learn your patterns for new services. Don’t expect accurate alerts on day one.
Daily summaries exist. If individual alerts feel like too much, you can switch to daily digest emails. I use individual for production accounts and daily for dev.
Tag your resources. You can create monitors based on cost allocation tags. If you tag by team or project, you can send alerts to the right people automatically.
Total Cost to Run This
Cost Anomaly Detection: Free
Lambda invocations: Maybe $0.10/month if that
SNS notifications: Cents
The whole thing costs practically nothing to run.
Conclusion
Look, cloud cost management isn’t glamorous. Nobody’s going to pat you on the back for setting up billing alerts. But when you catch a runaway service before it racks up a four-figure bill, you’ll be glad you spent the hour setting this up.
The basic setup (Part 1 and 2) takes maybe 10 minutes. That alone will save you from most surprises. Add the Lambda formatting if you want nicer alerts. Add the EventBridge rule if you’re paranoid about expensive instances like I am now.
For further actions, you may consider blocking this person and/or reporting abuse
Залишити відповідь