Order of magnitude from a typical scale-up audit: the monthly share of each hidden cost, once isolated from the rest.
Billed per hour AND per GB processed. Every call from a private instance to the internet goes through it. A VPC Endpoint for S3/DynamoDB bypasses the NAT — and the cost.
Getting data out of AWS is expensive; cross-region or cross-AZ too. Serve assets via CloudFront and keep traffic within one AZ where you can.
Every automatic backup piles up and never expires on its own. Without a retention policy, you pay for years of dead backups.
500 GB volumes used at 40, logs kept forever. Size to actual use and set an expiration.
NAT Gateway is trap number one: invisible inside “EC2,” it can exceed the cost of your instances. It's always the first line I go hunting for.
A NAT Gateway isn't expensive because it's switched on — it's expensive because every byte leaving a private subnet passes through it, and you pay $0.045/hour PLUS $0.045 per GB processed. Every `GET` to S3, every DynamoDB query, every `docker pull` from a private instance stacks up. So the question isn't “how do I pay less for the NAT” but “which traffic has no business going through it.”
S3 and DynamoDB offer gateway endpoints that inject a route into your route table and bypass the NAT entirely — no internet gateway, no NAT device. The clincher: `There is no additional charge for using gateway endpoints`. No hourly fee, no per-GB fee. On a data-heavy setup pulling terabytes from S3 out of private subnets, that single change drops the NAT line by hundreds of dollars a month. It's the first thing I set up on an audit, because the effort-to-payoff ratio is indecent.
Classic trap: the gateway endpoint is regional. If your instance in eu-west-1 reads a bucket in us-east-1, traffic goes back through the NAT and cross-region egress. Keep buckets and tables in the same region as the VPC, otherwise the endpoint buys you nothing.
For ECR, Secrets Manager, SSM or internal AWS APIs, those are interface endpoints (PrivateLink) — billed, but the moment a cluster pulls images all day, the endpoint cost stays under the NAT it replaces. I always run the math first: monthly volume × $0.045 on the NAT side, versus the endpoint's hourly flat fee. Below a certain throughput, keeping the NAT is still the smarter call.
gp3 costs up to 20% less per GB than gp2, with a guaranteed baseline of 3,000 IOPS and 125 MiB/s regardless of size. That's the real lever: on gp2 you over-provision the volume just to scrape IOPS (IOPS is tied to size). On gp3 you decouple IOPS and throughput from storage — so you can often shrink the volume and keep the performance. AWS shows a 2 TB gp2 volume at $200/month replaced by a 1 TB gp3 at equivalent performance for $100: 50% off, not 20. Migration runs through Elastic Volumes, live, no detach and no instance restart.
My rule: every new volume is born gp3, and I batch-migrate the existing ones. The only case where I slow down is a volume already past 16,000 provisioned IOPS — there you re-compute, otherwise default gp3 will underperform.
By default a log group keeps its logs forever — nobody checks that box at creation, and that's exactly the problem. Two levers: first set retention on EVERY log group (7, 30, 90 days depending on use), then switch eligible groups to the Infrequent Access class, which halves the ingestion price ($0.25/GB versus $0.50/GB Standard). Since early 2026, IA supports full Logs Insights queries, so for application logs that don't need real-time metric filters, that's the default I recommend.
Snapshots, detached volumes, log groups without retention: you can hunt them all once. But the next leak comes from what you're not watching yet. So I turn on AWS Cost Anomaly Detection, which runs an ML model on net cost and alerts by email or SNS (relayable to Slack) the moment a line drifts, ranking the cause by service, account, region or usage type. It's free, runs ~3 times a day, and needs ~10 days of history to calibrate. One blind spot to know: Marketplace products, including third-party LLMs on Bedrock, aren't covered — for those, an AWS Budget takes over.