Skip to content
Why Is AWS "Expensive"? The Hidden Costs No One Tells You
← ← Back to Thinking Cloud

Why Is AWS "Expensive"? The Hidden Costs No One Tells You

AWS isn't expensive. AWS is unpredictable. And unpredictability hurts more than a high but clear price. At Hetzner you pay €15/month and you know exactly what you get. At AWS you pay $150/month, then next month you get a $380 bill and don't understand why.

We've talked in previous articles about migrating to AWS, zero-downtime deployment, and serverless. They all have huge advantages. But it's only fair to talk about the other side too: the costs you don't see in the AWS pricing calculator but that show up on your bill.

Anatomy of an AWS bill

An AWS bill isn't a single number. It's a list of dozens of line items, each with its own billing metric. EC2 is charged per hour. EBS per GB stored per month. S3 per GB stored PLUS per request. Data transfer per GB transferred. ALB per hour PLUS per LCU. And each service has different prices per region.

Result: a simple app can generate 15–20 distinct costs, of which maybe 5 you anticipated and the rest are "surprises."

Top 7 hidden costs on AWS

1. Data transfer — the biggest gotcha

Data going into AWS is free. Data going out — not so. Outbound traffic to the internet costs $0.09/GB (first 100 GB/month free). Seems small, but for an app serving images, video, or APIs with large payloads, costs explode.

And less obvious: data transfer between Availability Zones costs $0.01/GB in each direction. EC2 in one zone and RDS in another? Every query pays a crossing fee. Multi-AZ ALB routing traffic? Half the traffic crosses zones. At scale, this can cost tens of dollars per month without you noticing.

2. Public IPv4 addresses — $3.65/month per IP

Since February 2024, AWS charges for ALL public IPv4 addresses at $0.005/hour (~$3.65/month), whether used or not. Before, only unattached Elastic IPs cost money. Now you pay for every public IP: on EC2, on the ALB (which gets at least 2 IPs), on NAT Gateway, on RDS if public.

A typical architecture with ALB + 2 EC2 + NAT Gateway + RDS has 6–7 public IPs. That's ~$25/month just for IP addresses. No one told you that during planning.

3. NAT Gateway — the invisible tax

If EC2 instances are in private subnets (security best practice), they need a NAT Gateway for internet access. NAT Gateway costs $0.045/hour ($32.85/month) just for existing, PLUS $0.045/GB for every gigabyte processed, PLUS the associated public IP ($3.65/month).

Run npm install on an instance? Traffic goes through NAT Gateway. Instances health-check external services? NAT Gateway. Download package updates? NAT Gateway. An architecture with NAT Gateway in 2 AZs costs at least $70/month before you send the first byte of real data.

Solution: VPC Endpoints for AWS services (S3, DynamoDB, ECR) — free or much cheaper than routing through NAT Gateway.

4. EBS volumes and snapshots

When you stop an EC2 instance, you stop paying for compute. But the attached EBS disk keeps generating costs ($0.10/GB/month for gp3). 100 GB storage on a stopped instance is $10/month. Seems small, but you have 5 dev instances you stop Friday night? $50/month for idle disks.

EBS snapshots (backups) cost $0.05/GB/month. And they're incremental, so they don't necessarily take the full original volume space — but they add up. I've seen accounts with hundreds of orphan snapshots costing hundreds of dollars per month.

5. CloudWatch logs — the cost of monitoring

CloudWatch comes "free" with AWS, right? Not exactly. Log ingestion costs $0.50/GB. Log storage costs $0.03/GB/month. A Node.js app logging HTTP requests, errors, and debug info can easily generate 10–30 GB of logs per month. That's $5–15/month just on log ingestion.

And if you create custom metrics or dashboards, each custom metric costs $0.30/month (first 10 free). 50 custom metrics? $12/month. Alarms? $0.10 each per month.

6. Unused Elastic IPs and orphaned resources

An extremely common pattern: you create an Elastic IP for testing, disassociate it from the instance, and forget about it. Unattached Elastic IP costs $0.005/hour ($3.65/month). Load balancers with no targets? Charged the same as active ones ($18/month minimum). Security groups, ENIs, and other non-compute resources don't cost directly, but can point to associated compute resources you've forgotten.

7. RDS extended support

If you run PostgreSQL 12 on RDS and don't upgrade, AWS automatically puts you on Extended Support once the version reaches end-of-life. That adds an extra cost per vCPU per hour — and they don't announce it with fanfare. You can wake up with your RDS bill doubled without changing anything.

Why prices change (and how to find out)

AWS changes prices more often than you think. The 2024 IPv4 fee is just the most visible example. Other recent changes: from August 2025, Lambda charges the INIT (cold start) phase of functions, previously free. RDS Extended Support was automatically enabled on old versions. The free tier was restructured in July 2025 — new accounts get credits instead of free hours, which works differently.

How do you find out about changes? Monitor the official AWS Blog, subscribe to the AWS Pricing Changelog, and check AWS Cost Explorer monthly. But most important: set a Billing Alarm that alerts you when costs exceed a threshold.

How to protect yourself: AWS tools

AWS Budgets — set a monthly budget (e.g. $200) and get email alerts at 50%, 80%, 100%, and forecast overrun. The first budget is free. It's the most important thing to do on your AWS account, before any other service.

Cost Explorer — visualize costs by service, region, tag. Spot trends and anomalies. Available free in the console.

AWS Cost Anomaly Detection — uses machine learning to detect unusual costs and alerts you automatically. Free and extremely useful.

Trusted Advisor — automatically checks for idle resources (unused EC2, EBS, EIPs) and recommends optimizations. The base version is free.

Resource tagging — tag every resource with project, environment (dev/staging/prod), and owner. Then filter by tags in Cost Explorer and see exactly what each project costs. Without tags, you don't know what to optimize.

Concrete cost reduction strategies

Reserved Instances and Savings Plans — if you know you'll run RDS and EC2 for at least a year, you save 30–40% with a commitment. Savings Plans are more flexible (apply to any instance type in a family).

Rightsizing — most instances are oversized. A t3.medium at 15% CPU utilization can be a t3.small at half the price. AWS Compute Optimizer recommends exactly what you need.

Automatic scheduling — dev and staging environments don't need to run 24/7. A Lambda script that stops non-prod environments at 8pm and starts them at 8am saves 50% of compute cost. Weekends add another 30%.

VPC Endpoints — for traffic to S3, DynamoDB, ECR. Eliminates NAT Gateway cost for internal AWS traffic. An S3 Gateway Endpoint is completely free.

S3 lifecycle policies — move old data from Standard ($0.023/GB) to Glacier ($0.004/GB). Logs older than 30 days probably don't need instant access.

Verdict: is it worth it?

AWS isn't expensive per se — it's complex. Complexity creates unexpected costs for those who don't understand it. A Hetzner CX33 at €5.49/month all-inclusive (traffic, IP, storage) is unbeatable on pure price. But it doesn't give you automatic failover, elastic scalability, compliance, or enterprise SLAs.

The real difference is between visible cost (the bill) and total cost of ownership (TCO). Your hours administering a VPS, downtime risk, backup setup time, and lack of scalability all have a price — it just doesn't appear on a bill.

The secret is to go into AWS with your eyes open: set billing alarms from day 1, tag everything, review the bill monthly, and don't leave orphaned resources. "Expensive" AWS is really unmanaged AWS.


Published on teninvent.ro — TEN INVENT S.R.L. provides AWS cost audit and optimization. Contact us for a free analysis of your cloud bill.