You built a small side project on AWS. Traffic is basically zero. Yet every month the bill creeps up, and the line items look like error codes: USE1-NatGateway-Hours, USE1-PublicIPv4:InUseAddress...
If that sounds familiar, you're not bad at AWS. Most surprise bills come from the same five causes, and each one takes only a few minutes to check.
Note: Prices below are AWS list prices for US East (N. Virginia), checked in November 2026. Other regions can cost more, and AWS updates prices over time. Always confirm on the official pricing pages (links at the end).
- Resources that charge just for existing
Many AWS services bill by the hour, not by how much you use them. If the resource exists, the meter is running.
The classic example is the NAT Gateway:
$0.045 per hour, which is about $32.85 a month, even with zero traffic
Plus $0.045 per GB of data it processes
Lots of beginner tutorials create a NAT Gateway so private subnets can reach the internet. The tutorial ends, the gateway stays.
Other usual suspects:
Public IPv4 addresses. Since February 1, 2024, every public IPv4 address costs $0.005 per hour (about $3.60 a month), whether it's attached to something or not.
EBS volumes from instances you stopped or terminated. The disk can outlive the server.
Load balancers with no traffic.
RDS databases left running 24/7 for a test you finished weeks ago.
Quick check: find unattached EBS volumes and unused Elastic IPs in your current region:
bash
aws ec2 describe-volumes --filters Name=status,Values=available \
--query "Volumes[].[VolumeId,Size]" --output text
aws ec2 describe-addresses \
--query "Addresses[?AssociationId==null].[PublicIp,AllocationId]" --output text
If anything shows up that you don't need, delete it. Stopping isn't always enough.
- Resources hiding in another region
The AWS console only shows resources in the region you currently have selected.
So if a tutorial had you build in N. Virginia (us-east-1) but you normally work in Oregon (us-west-2), those first resources seem to vanish. They haven't. They're still running, and still billing.
Quick check (console): open Resource Groups & Tag Editor → Tag Editor, set Regions to All regions and Resource types to All supported resource types, then search. Anything you don't recognize deserves a closer look.
Quick check (CLI): list EC2 instances in every region:
bash
for r in $(aws ec2 describe-regions --query "Regions[].RegionName" --output text); do
echo "== $r"
aws ec2 describe-instances --region "$r" \
--query "Reservations[].Instances[].[InstanceId,State.Name]" --output text
done
- Data transfer and logs that add up quietly
Data transfer out: sending data from AWS to the internet costs money. You get 100 GB per month free, but that allowance is shared across all regions combined, not per region. Serving images or video straight from an EC2 instance can burn through it quickly.
CloudWatch Logs: ingesting logs costs $0.50 per GB, plus about $0.03 per GB per month to store them. Two things make this sneaky:
Verbose debug logging you turned on "just for today" and never turned off.
Log groups keep data forever by default.
Quick fix: set a retention period on your log groups:
bash
aws logs put-retention-policy --log-group-name "/aws/lambda/my-app" --retention-in-days 14
- Assuming "Free Tier" means "free"
AWS overhauled its Free Tier on July 15, 2025, and a lot of tutorials still describe the old model.
If your account was created on or after July 15, 2025, you chose one of two plans at sign-up:
Free plan: starts with $100 in credits (up to $100 more for completing onboarding activities). It's designed so you aren't charged. It ends after 6 months or when your credits run out, whichever comes first, and the account is closed unless you upgrade.
Paid plan: same credits, but once they're used up, normal charges apply automatically.
If your account was created before July 15, 2025, you're on the legacy Free Tier: 12-month trials with usage limits per service. Go over a limit, and you pay.
Either way, "free" has conditions. Check which model applies to you before you trust a tutorial's "this costs nothing" claim.
- Leaked access keys
This is the scary one.
Security researchers have planted AWS access keys in public GitHub repos to see what happens. In those experiments, attackers found and started using the keys within 1 to 2 minutes. A common move is to launch the largest instances they can, often for cryptocurrency mining.
These bills don't stop at tens of dollars.
Quick checks:
Search your repos (including old commits) for AKIA, the prefix of AWS access key IDs.
In IAM, deactivate any access keys you don't actively use.
Never create access keys for your root user, and turn on MFA for it.
The root problem: no automatic spending cap
All five causes share one thing. Unless you're on the new Free plan, AWS has no built-in spending cap that shuts everything down for you. It's not like a prepaid phone plan. If you don't notice, the charges keep coming.
So the first priority is a system that tells you early:
AWS Budgets: create a monthly cost budget with an email alert at 80% of an amount you're comfortable with. Budgets that only send notifications are free.
Cost Anomaly Detection: it learns your normal spending and alerts you when something looks off, at no additional cost. It's on by default for accounts that enabled Cost Explorer after March 2023, but check that the alerts go to an inbox you actually read.
One catch: budget data updates up to three times a day, typically 8 to 12 hours apart. An alert is a smoke detector, not a sprinkler. It tells you early; it doesn't put out the fire.
Wrapping up
Most surprise AWS bills aren't mysterious. They're idle resources, forgotten regions, chatty logs, Free Tier assumptions, or leaked keys. Spend 30 minutes setting up alerts and sweeping all regions, then 10 minutes a month reviewing your bill, and you'll catch almost all of it.
If you'd like the whole thing as a step-by-step setup, I put together a short PDF guide: a 30-minute action plan, copy-paste CLI commands, and a 10-minute monthly checklist. It's $9 on Gumroad: Stop AWS Bill Shock. Everything in this article works without it, though.
Sources (checked November 2026)
Amazon VPC pricing (NAT Gateway, public IPv4)
AWS News Blog: Public IPv4 address charge
AWS Global Network FAQs (100 GB free data transfer out)
Amazon CloudWatch pricing
AWS News Blog: Free Tier update, July 2025
AWS Budgets pricing
AWS Budgets user guide (update frequency)
Orca Security: 2023 Honeypotting in the Cloud Report
Comparitech: AWS credentials on GitHub abused within 1 minute

