Why Is My NAT Gateway So Expensive? NAT vs VPC Endpoints

2–3 minutes

Updated

Short answer: a NAT Gateway charges twice: once per hour it exists and again for every GB it processes. If workloads in private subnets talk to S3 or DynamoDB through it, you pay for traffic that a free gateway endpoint would carry instead.

LabEstimated · not yet run
Time
40 min
Cost
≈ US$ 1
Level
Intermediate
Services
VPC · NAT · S3

How NAT Gateway billing works

In us-east-1, the public price is US$ 0.045 per hour per NAT Gateway and US$ 0.045 per GB processed, in either direction. Data transfer charges (for example to the internet or across AZs) come on top. Prices vary by region, so check the VPC pricing page for yours.

US$ 32.85 / month

One NAT Gateway running all month (730 hours × US$ 0.045), before any GB is processed. One gateway per AZ for high availability multiplies this.

The hourly part is predictable. The per-GB part is where bills surprise people: pulling container images, writing logs or reading objects from S3 through the NAT all count as processed bytes.

Step 1: Confirm the NAT is the expensive line

Group your cost by usage type and look for entries ending in NatGateway-Bytes and NatGateway-Hours. The prefix changes by region (for example USE1-).

cost-by-usage-type.sh

aws ce get-cost-and-usage \
  --time-period Start=2026-09-01,End=2026-10-01 \
  --granularity MONTHLY --metrics UnblendedCost \
  --group-by Type=DIMENSION,Key=USAGE_TYPE \
  --query 'ResultsByTime[0].Groups[?contains(Keys[0], `NatGateway`)]' \
  --output table

Step 2: Find what the NAT is talking to

Enable VPC Flow Logs on the NAT Gateway network interface and look at the destinations with the most bytes. If the top destinations are S3 or DynamoDB IP ranges, the fix is cheap. If they are external APIs or package mirrors, you need a different strategy (caching, a proxy, or keeping the NAT).

Step 3: Move S3 and DynamoDB traffic to gateway endpoints

Gateway endpoints for S3 and DynamoDB have no hourly or per-GB charge. They are added to route tables, so traffic from those subnets stops going through the NAT.

create-s3-gateway-endpoint.sh

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0abc1234 \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids rtb-0private1 rtb-0private2

Interface endpoints (PrivateLink) are not free: they charge per hour per AZ and per GB. They still make sense for services like ECR or CloudWatch Logs when the NAT traffic to them is large, but do the math first.

NAT Gateway vs VPC endpoints

OptionHourly (us-east-1)Per GBUse it for
NAT GatewayUS$ 0.045US$ 0.045 processedInternet egress from private subnets
Gateway endpoint (S3, DynamoDB)US$ 0US$ 0S3 and DynamoDB from private subnets
Interface endpointUS$ 0.01 per AZUS$ 0.01 (first PB)Other AWS APIs with heavy traffic

Prevent it from coming back

  • Create the S3 and DynamoDB gateway endpoints in your VPC module, so every new VPC has them.
  • Set an AWS Budgets alert on the NatGateway-Bytes usage type.
  • Turn on Cost Anomaly Detection for EC2-Other, where NAT charges show up.

Prices above are the public us-east-1 list prices at the time of writing. Check the pricing page before you rely on them.

Run the numbers for your account

Use the NAT Gateway vs VPC endpoints calculator with your own traffic and prices.

Open the calculator →

Joniel Gallo · Cloud & AI Engineer

I build these labs in a real AWS account and publish the code. Need a second opinion on your architecture or your AWS bill? Work with me.

One tested AWS & AI lab a week

Real costs, working code and what changed in Bedrock this month. Subscribe and get the free AWS Permission Debugger (PDF).