NAT Gateway is one of the most quietly expensive services in AWS. The pricing looks reasonable on paper — but the way AWS networks are typically built means NAT Gateway ends up processing traffic it was never meant to handle, and the charges compound in ways that don't show up clearly on your bill until they're already large.
This post covers the specific patterns that drive NAT Gateway costs higher than they should be, why they're so hard to spot, and what it actually takes to fix them.
How NAT Gateway Pricing Works
NAT Gateway has two cost components:
Hourly charge
Per NAT Gateway, per Availability Zone. A standard multi-AZ setup with one NAT per AZ costs ~$97/month before a single byte flows through it.
Data processing charge
Per GB processed in either direction. No free tier. No cap. Every gigabyte your workloads route through NAT costs $0.045 — including traffic to services with free private routing paths.
Pattern 1 — S3 Traffic via NAT Gateway
S3 via NAT
Typical saving: $200–$500/moWhen an EC2 instance in a private subnet accesses S3 and no S3 VPC Gateway Endpoint is configured, the traffic exits through the NAT Gateway to the public S3 endpoint and returns the same way. Every GetObject, PutObject, and ListObjects call processes through NAT at $0.045/GB.
AWS provides S3 VPC Gateway Endpoints at no charge. Once configured, S3 traffic routes privately inside the AWS network — the NAT Gateway is bypassed entirely and the processing charge disappears.
The reason this pattern is so widespread: it is the default. A private subnet with a NAT Gateway and no S3 endpoint is the standard "secure private subnet" setup. Most teams configure it this way without realising that every S3 operation incurs a NAT charge.
aws ec2 create-vpc-endpoint \
--vpc-id <your-vpc-id> \
--service-name com.amazonaws.us-east-1.s3 \
--route-table-ids <your-private-route-table-id>
Pattern 2 — AWS API Calls via NAT Gateway
AWS APIs via NAT
Typical saving: $30–$150/moEC2 instances calling AWS service APIs — SSM, CloudWatch, Secrets Manager, STS, KMS — do so over HTTPS to public endpoints. In a private subnet with a NAT Gateway, these calls route out through NAT and back.
The data volumes per call are small — a Secrets Manager GetSecretValue response is a few kilobytes. But high-call-rate services accumulate: a fleet of 50 EC2 instances polling SSM Parameter Store every 30 seconds generates millions of API calls per day. CloudWatch PutMetricData calls from containerised workloads at high frequency compound further.
Interface VPC Endpoints for these services cost approximately $7.30/month per endpoint per AZ. For any service being called more than roughly 160 GB/month through NAT, an Interface Endpoint pays for itself.
Create Interface VPC Endpoints for the AWS services your workloads call most frequently. Start with SSM, CloudWatch, and Secrets Manager — these are the most commonly overlooked.
Pattern 3 — NAT Gateway in the Wrong Availability Zone
NAT in wrong AZ
Typical saving: $20–$100/moNAT Gateways are AZ-specific resources. When an EC2 instance in us-east-1b routes through a NAT Gateway in us-east-1a, the traffic crosses an Availability Zone boundary. AWS charges $0.01/GB in each direction for cross-AZ data transfer — on top of the $0.045/GB NAT processing fee.
The correct architecture is one NAT Gateway per AZ, with instances routing to the NAT Gateway in their own AZ. Many teams deploy a single NAT Gateway to reduce the hourly cost — inadvertently adding per-GB cross-AZ charges that can exceed the savings from running fewer gateways.
Deploy a NAT Gateway in each AZ where you have private subnet instances, and update route tables so each private subnet routes to the NAT Gateway in the same AZ.
Pattern 4 — ML Workloads Writing Checkpoints via NAT
ML checkpoints via NAT
Typical saving: $300–$2,000/moGPU training jobs are high-throughput S3 users. Modern large language models write checkpoints every few hundred training steps — checkpoint sizes range from a few gigabytes for smaller models to hundreds of gigabytes for large ones.
If the training VPC has no S3 VPC Gateway Endpoint, every checkpoint write routes through NAT at $0.045/GB. A training run that saves 50 GB checkpoints every hour, running for 72 hours, generates 3.6 TB of S3 writes through NAT — $162 in NAT charges for a single training run.
This pattern is especially costly because the volumes are large, the frequency is high, and the traffic is entirely internal to the AWS network — making the NAT charge a pure tax on avoidable routing.
aws ec2 create-vpc-endpoint \
--vpc-id <your-training-vpc-id> \
--service-name com.amazonaws.us-east-1.s3 \
--route-table-ids <your-private-route-table-id>
Why These Costs Are Hard to See
AWS Cost Explorer shows NAT Gateway charges as a single line item: NAT Gateway — Data Processed. It does not break down which traffic patterns contributed to the charge, which VPCs or instances generated it, or whether any of it could have been avoided.
To identify which traffic is routing through NAT and whether that traffic has a cheaper path, you need to analyse VPC Flow Logs — the raw network telemetry AWS generates for every connection. Flow Logs record the source, destination, port, protocol, and byte count for every flow. They are the only data source that can tell you what your NAT Gateway is actually processing.
How Netway Finds These Patterns Automatically
Netway's Lambda runs inside your AWS account, queries your VPC Flow Logs via Athena, and identifies the specific traffic patterns generating avoidable NAT charges. For each finding, Netway reports:
- ✓ The VPC and specific instance generating the traffic
- ✓ The pattern detected (S3 via NAT, AWS APIs via NAT, NAT in wrong AZ)
- ✓ The estimated monthly cost extrapolated from the traffic volume
- ✓ The exact CLI command to fix it
Your flow log data never leaves your AWS account.
Getting Started
Register at netway.basavytix.com
Run the CloudFormation deploy command shown in your dashboard
Run the scan
Review NAT Gateway findings and estimated monthly savings on the Cost tab