The AWS line items that surprise small teams
Picture a small team's first AWS invoice after a migration. The architecture diagram says the bill should be around ₹38,000. The invoice says ₹1,47,000. The gap is rarely a misconfiguration — it is a set of services that start charging the moment they are used, without a dashboard widget or an alarm.
We have seen this pattern enough times that we now check five specific line items before the invoice does.
**NAT Gateway data processing.** A NAT Gateway costs ₹0.23/hour just to exist, which is reasonable. The surprise is ₹0.023 per GB processed. A single ECS task pulling a 2 GB Docker image from Docker Hub through the NAT Gateway costs roughly ₹0.05. Do that across a fleet of twenty containers redeploying twice a day, and you have ₹60/day in NAT processing alone. Add a few chatty services pulling from external APIs and it is easy to reach ₹15,000 to ₹20,000 a month this way before anyone notices.
The fix is usually a VPC endpoint for ECR (`com.amazonaws.region.ecr.api` and `ecr.dkr`), which routes container pulls through the AWS network instead of through the NAT Gateway. The endpoint itself costs ₹0.052/hour, but the per-GB processing drops to zero.
**CloudWatch Logs ingestion.** Every `console.log` in a Lambda function is a log event. CloudWatch charges ₹0.35 per GB ingested. A noisy Lambda logging 1 KB per invocation, invoked 2 million times a month, generates 2 GB of logs — ₹700. The common version of this is a Node.js Lambda logging the full event payload on every invocation because the framework defaults to it. Multiply the payload size by the invocation count and a few thousand rupees a month disappears into log storage that nobody reads. Three lines of code remove it.
**EBS snapshots without lifecycle policies.** EBS volumes are cheap. Snapshots are cheaper — ₹0.095/GB-month. But a daily snapshot of a 100 GB volume, with no deletion policy, accumulates 3 GB of snapshot storage per month (snapshots are incremental). After a year, that is 36 GB of snapshots for a single volume. Multiply by twenty volumes across staging and production, and the line item is ₹6,840/month for backups no one ever restores from.
We set `DeleteSnaphotAfterDays` in a DLM lifecycle policy. Seven days is usually enough for most teams. Thirty days for production databases.
**Load Balancer idle time.** An Application Load Balancer costs ₹0.0224/hour — ₹16,410/year — plus ₹0.0075 per LCU-hour. The idle cost is the base rate. A staging environment with an ALB running 24/7 that receives traffic for two hours during QA is paying for 22 hours of idle ALB per day. We move staging ALBs behind a scheduled stop/start using EventBridge and Lambda. The ALB itself cannot be stopped, but the EC2 targets can, and if staging is truly unused overnight, we tear down the ALB and recreate it with Terraform in the morning.
**S3 multipart upload leftovers.** When a multipart upload is initiated but not completed or aborted, the uploaded parts persist in S3 and are billed at standard storage rates. A media bucket that has been taking user uploads for a couple of years can easily hold a few hundred gigabytes of orphaned parts — 340 GB works out to roughly ₹2,380/month for files that do not exist in any listing. The fix is a bucket lifecycle rule:
{
"Rules": [
{
"ID": "AbortIncompleteMultipartUploads",
"Status": "Enabled",
"AbortIncompleteMultipartUpload": {
"DaysAfterInitiation": 7
}
}
]
}We add this rule to every S3 bucket on day one now.
To find these before the invoice arrives, we enable AWS Cost Anomaly Detection on all accounts. It is free. Alerts go to Slack via SNS. The detection is not perfect — it tends to miss charges like the NAT Gateway one because they grow gradually — but it catches the sharp spikes, which are usually the expensive mistakes.
For gradual creep, we use Cost Explorer with a daily granularity view filtered by service. A seven-day lookback compared to the previous seven days catches most drift. We check this every Monday morning before standup. It takes four minutes and has paid for itself more times than we can count.