← All posts

Why your AWS bill is 3x your estimate

There's a pattern that repeats every quarter on r/aws and Hacker News: someone posts their AWS bill, far higher than they expected, and the comments fill up with "did you know about NAT Gateway / cross-AZ traffic / CloudWatch Logs / public IPv4?" The default AWS pricing calculator doesn't flag any of these.

NAT Gateway is $32/month per AZ + per-GB

A standard "private subnets need internet access" pattern uses a NAT Gateway. AWS charges $0.045/hour ($32/month) per NAT Gateway plus $0.045/GB of data processed.

For high availability you want one NAT Gateway per AZ — so a 3-AZ deployment is $96/month base before any data. A web app pulling 500GB/month through it adds another $22.50. That's ~$120/month for "internet access for private subnets" — a line item most cost estimates don't include.

The fix is a NAT Instance (DIY) or VPC endpoints for AWS services (S3 Gateway endpoint is free, the others are $7.30/month per endpoint per AZ).

Cross-AZ traffic is $0.01/GB each way

Data transferred between availability zones in the same region costs $0.01/GB on the sending side AND $0.01/GB on the receiving side. So a workload that produces 1TB/month of cross-AZ traffic pays $20/month — which doesn't sound like much until you realize many real-world apps push 10–50 TB.

This shows up in unexpected places: an Application Load Balancer in three AZs balancing to backends in three AZs has 2/3 of traffic crossing AZs. EKS pods landing on nodes in different AZs from their service. Replicated databases.

CloudWatch Logs at $0.50/GB ingestion

CloudWatch Logs charges $0.50/GB to ingest. Verbose application logging (debug level, JSON-stringified objects) easily produces 10–100GB/month per service. A handful of microservices logging at debug level can hit $200/month in CloudWatch Logs alone.

Plus storage at $0.03/GB-month and queries via Logs Insights at $0.005/GB scanned. Forgot to set retention on a log group? Old logs accumulate forever.

The single best AWS cost optimization most teams haven't done: set log retention on every CloudWatch log group. Default is "never expire". 90 days is plenty for most operational logs.

Public IPv4 now costs $3.65/month per IP

Since February 2024, AWS charges $0.005/hour for every public IPv4 address — about $3.65/month per IP. This applies to every EC2 instance with a public IP, every NAT Gateway, every Network Load Balancer, every API Gateway custom domain.

A typical small startup running 20 EC2 instances with public IPs is now paying ~$73/month for what was free pre-2024. Migrating to IPv6 or putting instances behind a single load balancer is the fix.

The architecture-level estimation problem

AWS's own calculator asks you to configure each service: "How many EC2 instances? What size? What storage?" That's the wrong abstraction. The right abstraction is "what kind of workload?": web app vs serverless API vs batch processing vs ML training.

A static site has different cost characteristics than a serverless API which has different characteristics than a container app. NAT Gateway costs are zero for static sites, dominant for container apps, irrelevant for serverless. Configuring 50 service-level inputs to discover this is wrong.

Our AWS cost calculator works by workload pattern (static site, serverless API, web app, container app, ML inference, ML training, backup). Pick the pattern, fill in 3–5 inputs, get a service-by-service breakdown that includes the actual gotchas — NAT Gateway, cross-AZ, CloudWatch Logs, public IPv4. Honest defaults so you see a realistic number in 5 seconds.

Try the tool