NAT gateway cost is an hourly fee per gateway plus a fee per gigabyte processed; a gateway nothing flows through pays the hours anyway, and one gateway per availability zone and subnet multiplies them. The same holds for interface endpoints, Private Link endpoints and Cloud NAT gateways, which are billed by the hour whether bytes pass or not. The saving comes from deleting a gateway without traffic and from merging several gateways per zone into one per zone where the architecture allows it. The fix belongs to the team that maintains the network templates, because gateways come from templates, not from decisions.
Symptom
The bill shows gateway hours without bytes. On AWS these are lineItem/UsageType EUC1-NatGateway-Hours with no EUC1-NatGateway-Bytes of note under AmazonEC2, plus EUC1-VpcEndpoint-Hours without VpcEndpoint-Bytes, per endpoint and zone. On Azure they are MeterCategory Virtual Network with NAT Gateway meters per hour and Data Processed per GB, and Private Link with endpoint hours. On Google Cloud Cloud NAT carries the SKUs for gateway hours per VM and for data processed, and Private Service Connect the endpoint hours. What NAT costs in principle and how the gateway sits in the glossary is in load balancers, NAT and public IPs and the term NAT gateway; this page covers gateways and endpoints without traffic.
How to detect it
AWS
The gateways with zone and subnet, and the endpoints with type and service:
aws ec2 describe-nat-gateways --filter Name=state,Values=available \
--query 'NatGateways[].[NatGatewayId,VpcId,SubnetId,NatGatewayAddresses[0].PublicIp,CreateTime]' --output table
aws ec2 describe-vpc-endpoints --filters Name=vpc-endpoint-type,Values=Interface \
--query 'VpcEndpoints[].[VpcEndpointId,VpcId,ServiceName,length(SubnetIds),CreationTimestamp]' --output table
One gateway's bytes over 30 days:
aws cloudwatch get-metric-statistics --namespace AWS/NATGateway --metric-name BytesOutToDestination \
--dimensions Name=NatGatewayId,Value=nat-0123456789abcdef0 --statistics Sum \
--start-time 2026-09-21T00:00:00Z --end-time 2026-10-21T00:00:00Z --period 86400
Four checks AWS runs (read on 2026-10-21): Trusted Advisor flags under "Inactive NAT Gateways" a gateway that processed 0 bytes in the last 30 days, under "Inactive VPC interface endpoints" an endpoint with 0 bytes in 30 days, and likewise inactive Gateway Load Balancer endpoints and Network Firewalls; Compute Optimizer classifies a gateway as idle that is available, sits in no route table and had neither active connections nor packets from source or destination over the lookback period:
aws compute-optimizer get-idle-recommendations --filters name=ResourceType,values=NatGateway
AWS lists USD 0.045 per gateway-hour and USD 0.045 per GB processed in US East (Ohio) (VPC pricing). In billing data the candidate is a NatGateway-Hours line with 720 hours and a NatGateway-Bytes line near zero for the same lineItem/ResourceId (AWS Cost and Usage Report).
Azure
The NAT gateways with subnets and addresses, and the private endpoints:
az network nat gateway list --query "[].{name:name, rg:resourceGroup, subnets:length(subnets), ips:length(publicIpAddresses), sku:sku.name}" -o table
az network private-endpoint list --query "[].{name:name, rg:resourceGroup, service:privateLinkServiceConnections[0].privateLinkServiceId}" -o table
One gateway's ByteCount metric over 30 days, as a sum per day (NAT gateway metrics):
az monitor metrics list --resource <nat-gateway-resource-id> --metric ByteCount --aggregation Total \
--interval P1D --start-time 2026-09-21T00:00:00Z --end-time 2026-10-21T00:00:00Z
Azure Advisor has no recommendation on NAT gateways or private endpoints without traffic; it flags, in preview, virtual network gateways with no connections and ExpressRoute circuits that were never provisioned. In the cost export the candidate is a natGateways/ resource with an hourly meter and no Data Processed (Azure cost exports).
Google Cloud
The Cloud NAT gateways per router and the Private Service Connect endpoints:
gcloud compute routers list --format="table(name,region.basename(),network.basename())"
gcloud compute routers nats list --router=<router> --region=<region> --format="table(name,natIpAllocateOption,sourceSubnetworkIpRangesToNat)"
gcloud compute forwarding-rules list --filter="target ~ serviceAttachments" --format="table(name,region.basename(),IPAddress,target.basename())"
The metric router.googleapis.com/nat/sent_bytes_count per gateway in Cloud Monitoring over 30 days is the evidence; Cloud NAT is billed per gateway-hour by the number of attached VMs and per GB processed (Cloud NAT pricing). There is no recommender for NAT. In the billing export the candidate is a Cloud NAT gateway SKU with full hours and no data SKU beside it (Google Cloud billing export).
How to fix it
- Settle per gateway whether it is part of a disaster recovery architecture, as Compute Optimizer explicitly asks: a gateway in the second zone that sees traffic only when the first fails is not a case for this page.
- Delete gateways and endpoints without traffic, from the list. AWS: check the routes first,
aws ec2 describe-route-tables --filters Name=route.nat-gateway-id,Values=nat-0123456789abcdef0, thenaws ec2 delete-nat-gateway --nat-gateway-id nat-0123456789abcdef0 --dry-runandaws ec2 delete-vpc-endpoints --vpc-endpoint-ids vpce-0123456789abcdef0 --dry-run, both without--dry-runonly after the release; the gateway's Elastic IP address stays and needsrelease-address. Azure:az network nat gateway delete --name <gateway> --resource-group <rg>andaz network private-endpoint delete, without a dry run. Google Cloud:gcloud compute routers nats delete <nat> --router=<router> --region=<region>andgcloud compute forwarding-rules delete. - Merge where several gateways run per zone: one NAT gateway per availability zone serving every private subnet of the same zone, instead of one per subnet; on AWS one endpoint per service and VPC, or a central endpoint in a shared VPC with private DNS forwarding. An example from the naming rules: three private subnets in
eu-central-1awith a gateway each pay three hourly fees, one per zone with three routes pays one. - Correct the template: one gateway per zone as the module default, gateway endpoints for S3 and DynamoDB, which carry no hourly fee, instead of interface endpoints, and a check in the review that justifies new gateways (cost in the development lifecycle).
The hourly fee ends with the deletion; the daily export shows it the next day.
Risks and side effects
- A gateway without traffic is sometimes the return path of a disaster recovery architecture; the route table and the tag say so, the owner decides.
- One gateway per zone instead of per subnet saves hours, but a subnet that reaches the internet through a gateway in another zone pays cross-zone transfer and loses its path in a zone outage; the merge stays within the zone (data transfer optimisation).
- A deleted interface endpoint sends traffic to the service back through the NAT gateway and pays per GB there; whether endpoint or gateway is cheaper depends on the volume.
- The Elastic IP address of a deleted NAT gateway stays allocated and keeps costing per hour until it is released (unused public IP addresses).
- Private endpoints have a security function beside the cost question; an endpoint without traffic that satisfies a "no public access" policy stays.
How to verify the saving
Before: per gateway and endpoint, the hour and the byte line in the last full month: NatGateway-Hours and NatGateway-Bytes, VpcEndpoint-Hours, the NAT gateway and Private Link meters, the Cloud NAT SKUs. After: the same resources in the first full month after the deletion or merge, expected zero, and beside them the byte line of the remaining gateways, which may rise by the redirected traffic. The sum of the deletion list's hourly fees is the estimate, the release makes it accepted, the deletion implemented, and the following month's invoice realises it in the pattern of estimated, accepted, implemented, verified. The number of gateways with zero bytes in 30 days is the figure that then stays at zero.
Sources
Read on 2026-10-21. Trusted Advisor cost optimization checks, Compute Optimizer idle resource recommendations, Amazon VPC pricing, describe-nat-gateways, Azure NAT Gateway metrics, Azure Advisor cost recommendations, Cloud NAT pricing, gcloud compute routers nats.