Unused NAT Gateways: the basics
What does an unused NAT Gateway actually look like?
A NAT Gateway is a managed appliance that lets resources in a private subnet reach the public internet without exposing them to inbound traffic. It's billed in two parts: a flat $0.045 per hour just for being provisioned — about $32.40 per gateway per month — plus $0.045 per GB of traffic processed. The hourly charge runs whether the gateway moves a single byte or terabytes; deletion is the only way to stop it.
An "unused" NAT Gateway is one whose CloudWatch BytesOutToDestination and BytesInFromDestination metrics are flat at zero (or near-zero) over a meaningful window — typically 7 days. It's still sitting in a VPC, still attached to an Elastic IP, still on the bill. The usual causes are mundane: a NAT-per-AZ pattern provisioned for redundancy even though only one AZ has subnets that need it, a NAT left behind after the workload migrated to VPC endpoints, or a dev VPC where the workload was decommissioned but the networking plumbing wasn't.
Wastage checks flag these because the signal is unambiguous: a managed service charging $32/month with no traffic flowing through it is by definition not earning its keep. The risk of deletion is also low — provided you confirm nothing is intermittently using it (cron jobs, weekly batch, monthly compliance scans) and that there's a route-table replacement for any subnet that depends on it.
In this lesson you'll learn how to identify NAT Gateways that aren't moving traffic, how to trace which subnets and workloads depend on them, when to replace a NAT with VPC endpoints (and when not to), and the safe-delete sequence that avoids the cross-AZ data-transfer trap. You'll see real CloudWatch metric pulls, route-table inspection, and the cost math for VPC endpoint replacement.
The NAT-per-AZ tax
AWS docs recommend a NAT Gateway per Availability Zone for high availability. Teams dutifully provision three — one in each AZ — and then deploy a workload that only ever has subnets in two of them. The third NAT sits idle for years, billing $32/month for redundancy that nothing is using. A 100-account organisation following the pattern by default is often quietly paying $30k+/year for NAT Gateways no workload ever routes through.
Hunting an unused NAT in action
Marco is doing a quarterly VPC audit for a fintech with 40-odd AWS accounts. His wastage tooling flags a NAT Gateway in the payments-staging VPC, eu-west-1c, with zero traffic for the last 30 days — $32.40/month wasted on the bill, and the resource has been there for 14 months.
Before deletion he wants two things confirmed: (1) the metric really is flat, not just averaged-flat (a weekly batch could be invisible at the hourly granularity) and (2) which subnets, if any, still route through it. Deleting a NAT that subnets still point at will break egress the moment something tries to use the route.
He starts with the CloudWatch metrics, then walks the route tables and security groups to see whether anything is even pointed at the gateway.
Pull 7 days of NAT Gateway traffic at 1-hour resolution to confirm there's no hidden batch pattern.
Flat zeros over 7 days at hourly granularity — a weekly batch would show up here.
Now find every route table pointing 0.0.0.0/0 at this NAT. Anything you see here will break egress the moment you delete the gateway.
A single subnet still routes through this NAT — even though no traffic is flowing today, deletion needs a route swap first.
How NAT Gateway billing actually worksdeep dive
A NAT Gateway is a managed Elastic Network Interface backed by AWS-managed infrastructure inside a single Availability Zone. The $0.045/hour provisioning charge is the cost of that ENI being parked and ready — it's billed by AWS the moment the gateway transitions to available, regardless of traffic. The processing charge ($0.045/GB) is on top, applied to every byte going through the gateway in either direction.
The bill compounds in two ways most teams miss. First, every NAT Gateway holds an Elastic IP, and an unattached EIP is itself billable ($0.005/hour ≈ $3.65/month) — though for an attached NAT the EIP charge is folded into the gateway charge. Second, traffic patterns matter: a workload sending lots of small requests to S3 from a private subnet routes through NAT and pays the $0.045/GB processing fee on every byte, when a VPC Gateway Endpoint for S3 would carry the same traffic for free.
Interface VPC Endpoints (the more general kind, used for most other AWS services) cost roughly $0.01/hour per endpoint per AZ — about $7.20/month each — plus $0.01/GB processed. The crossover with NAT is around 150 GB/month for a single endpoint: above that, the endpoint wins. For very high-volume AWS API traffic, replacing NAT with a handful of endpoints can collapse the NAT bill entirely while improving latency and removing internet-routed traffic from your AWS-to-AWS calls.
# Inspect a NAT Gateway's full state, including attached EIP and creation date.
aws ec2 describe-nat-gateways \
--nat-gateway-ids nat-0abc123def456 \
--query 'NatGateways[0].{State:State, CreateTime:CreateTime, SubnetId:SubnetId, EIP:NatGatewayAddresses[0].PublicIp, AllocationId:NatGatewayAddresses[0].AllocationId}'
# After deleting the NAT, release the EIP separately or it keeps billing $3.65/mo.
aws ec2 release-address --allocation-id eipalloc-0xxxxxxxxx What's the impact of leaving unused NAT Gateways running?
The direct cost is $32.40 per gateway per month — modest individually, but multiplied across an org with hundreds of VPCs and a NAT-per-AZ default, it compounds fast. A 100-account fintech defaulting to 3 NATs per VPC and averaging 4 VPCs per account is paying $1,200/account/year just on provisioning charges. A non-trivial fraction of that is moving zero traffic.
The bigger cost is hidden in the used NATs that should have been replaced. Workloads that hammer S3, DynamoDB, or SQS from private subnets route every byte through NAT at $0.045/GB. A single ML pipeline pulling 5 TB/month from S3 through NAT instead of a Gateway Endpoint is paying $225/month in processing — for traffic that should be free. The wastage check fires on the provisioning waste; the architectural review is what catches the processing waste.
There's a sneaky third-order effect too: cross-AZ data transfer. If a team consolidates from three NATs to one to save provisioning costs, traffic from subnets in the other two AZs now crosses AZ boundaries at $0.01/GB each way. For a noisy workload this can swamp the $64/month they saved on the deleted NATs. The math only works if the consolidating NAT serves subnets in its own AZ or if cross-AZ volume is low.
From a security and compliance angle, idle NAT Gateways also expand the attack surface for very little reason — they hold a public IP that's reachable from the internet's eyes (no inbound traffic, but the IP exists). For PCI / SOC 2 environments, idle networking primitives also clutter the architecture diagram you'll have to defend at audit.
How do you safely clean up unused NAT Gateways?
Deleting NAT is cheap; deleting it without checking is the way to take down egress for a workload that runs once a month. Run the four-step loop below for every flagged gateway.
1. Confirm zero traffic over a real window
Pull BytesOutToDestination and BytesInFromDestination at hourly granularity for at least 7 days, ideally 30. Daily averages can hide a weekly batch job; hourly granularity won't. If you see any non-zero hour, drill into VPC Flow Logs to identify the source before doing anything else.
2. Find every subnet routing through it
aws ec2 describe-route-tables --filters Name=route.nat-gateway-id,Values=... shows every route table with a route pointing at this NAT. For each, either confirm the subnet is empty (no ENIs) or re-point the route at a shared NAT in the same AZ or at a VPC endpoint — before deletion, not after. Forgetting this is how you take down a cron job that runs on the first of the month.
3. Consider VPC endpoints instead of a replacement NAT
If the workload that was using this NAT is talking primarily to AWS services, a Gateway Endpoint (S3, DynamoDB — both free) or a handful of Interface Endpoints ($7.20/mo each + $0.01/GB) is almost always cheaper than re-pointing to a shared NAT and paying $0.045/GB processing. Above ~150 GB/month per service the endpoint wins outright on cost, and it also avoids the internet round-trip for AWS-to-AWS calls.
4. Delete, then release the EIP, then watch for 24-48 hours
Run delete-nat-gateway, then release-address on the associated Elastic IP — easy to miss, and an orphaned EIP keeps billing $3.65/month. Watch CloudWatch and any application alerting for 24-48 hours afterwards; if a long-tail dependency surfaces you can recreate quickly. Tag the deletion in your change log so the next quarterly audit doesn't fire the same finding on a recreated gateway.
# 1. Delete the NAT Gateway (returns immediately; full teardown takes minutes).
aws ec2 delete-nat-gateway --nat-gateway-id nat-0abc123def456
# 2. Wait for it to fully delete before releasing the EIP.
aws ec2 wait nat-gateway-deleted --nat-gateway-ids nat-0abc123def456
# 3. Release the Elastic IP, or it keeps billing $3.65/month standalone.
aws ec2 release-address --allocation-id eipalloc-0xxxxxxxxx
# 4. Confirm no route tables still reference the deleted gateway.
aws ec2 describe-route-tables \
--query 'RouteTables[?Routes[?NatGatewayId==`nat-0abc123def456`]].RouteTableId' Quick quiz
Question 1 of 5A wastage check flags a NAT Gateway with zero BytesOutToDestination over the last 7 days. One route table still has a 0.0.0.0/0 route pointing at it, but the subnet has no running ENIs. What's the right next step?
You scored
0 / 5
Keep learning
Go deeper into NAT Gateway economics and the VPC endpoint patterns that replace them.
- AWS — NAT Gateway pricing and metrics Official docs covering NAT Gateway billing, CloudWatch metrics, and the per-AZ HA pattern.
- AWS — VPC endpoints overview Gateway endpoints (S3, DynamoDB) and Interface endpoints (everything else) — when each makes sense vs NAT.
- AWS Well-Architected — Cost Optimization Pillar Networking spend in the broader context of cost-aware architecture, including data-transfer patterns.
- FinOps Foundation — Cloud rate and usage optimization How idle-resource cleanup fits the FinOps lifecycle, and how to make it a continuous process.
You've completed Delete unused NAT Gateways. You now know the two-part NAT bill, how to confirm a gateway is genuinely idle, when a VPC endpoint is a better replacement than another NAT, and the four-step delete loop — confirm, re-route, delete, release. The next time the wastage tool flags one, you'll have the route-table check and the cross-AZ math ready before you reach for delete-nat-gateway.