AWS NAT Gateway costs: 3 alternatives that actually save money
NAT Gateway is the second-most-expensive AWS resource for many production workloads. Here's how to cut its cost by 60-90% using free VPC Gateway Endpoints, paid Interface Endpoints, and NAT instances.
Quick answer
AWS NAT Gateway costs about $32/month per NAT plus $0.045 per GB processed. To cut it: add free VPC Gateway Endpoints for S3 and DynamoDB, add Interface Endpoints for chatty AWS services like ECR and Secrets Manager, and consider NAT instances for small or non-critical workloads. A typical production VPC can save 60-90% on NAT costs without losing any functionality.
If you've ever opened the AWS Cost Explorer and seen NAT Gateway sitting near the top of your bill, you're not alone. NAT Gateway is the most commonly underestimated cost in AWS architectures, often the second or third largest line item after EC2. Three things make it expensive: the hourly rate compounds across AZs, the per-GB processing fee is unusually high for what the service does, and the traffic patterns of modern microservices funnel an enormous amount of data through it.
The good news is that NAT pricing is almost entirely avoidable with better routing. This post walks through the three alternatives that actually save money, with concrete savings figures and the Terraform you need to implement each one.
How NAT Gateway pricing actually works
A NAT Gateway has two pricing dimensions, and they're set at the same per-unit rate, which is the trap. The hourly rate is $0.045/hour (about $32.85/month per NAT). The data processing rate is also $0.045 per GB, in either direction.
Production-grade VPCs typically deploy one NAT Gateway per availability zone for high availability. A 3-AZ deployment is $98.55/month minimum, before any traffic flows through it. Then every GB of data crossing the NAT adds $0.045 more, in or out.
Where does the data come from? Three common patterns:
- Container image pulls. Every EKS or ECS task that pulls from Docker Hub, Quay, GitHub Container Registry, or any non-AWS registry pulls bytes through NAT.
- External API calls. Stripe, Twilio, GitHub, npm/PyPI, internal SaaS dependencies. All flow through NAT.
- S3 reads from private subnets without endpoints. If you read S3 objects from EC2/Lambda/ECS in a private subnet and haven't added a Gateway Endpoint, every byte goes through NAT and pays the processing fee, on top of S3 egress fees.
A workload that pulls 5 TB/month through NAT (modest for a production microservices fleet) pays $225 in processing fees per month, on top of the $98.55 base. That's $323/month before doing anything useful. At scale, the data fee dominates.
For the full pricing breakdown including a sample Terraform configuration and how C3X estimates NAT costs, see the aws_nat_gateway catalog page.
Alternative 1: VPC Gateway Endpoints (free)
This is the easy, no-downside win. VPC Gateway Endpoints route traffic to S3 and DynamoDB through a private AWS-internal path instead of through NAT. They're entirely free: no hourly fee, no data processing fee.
If your VPC has private subnets making any S3 or DynamoDB calls, adding Gateway Endpoints saves money immediately. The Terraform is ten lines:
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.us-east-1.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = aws_route_table.private[*].id
}
resource "aws_vpc_endpoint" "dynamodb" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.us-east-1.dynamodb"
vpc_endpoint_type = "Gateway"
route_table_ids = aws_route_table.private[*].id
}That's it. After applying, all S3 and DynamoDB traffic from the associated route tables bypasses NAT entirely. For S3-heavy workloads, this single change can cut NAT processing fees by 50%+. For more on these endpoints, see the aws_vpc_endpoint catalog page.
Concrete savings example
A typical data-processing pipeline that reads 50 TB/month from S3 to EC2 in private subnets pays:
- Without Gateway Endpoint: 50 TB × $0.045/GB = $2,250 in NAT processing fees
- With Gateway Endpoint: $0
Savings: $2,250/month. Implementation time: 10 minutes.
Alternative 2: Interface Endpoints for chatty AWS services
Interface Endpoints work for hundreds of AWS services that don't have Gateway Endpoints, including ECR, Secrets Manager, KMS, CloudWatch Logs, SSM, and SQS. They cost $0.01/hour per AZ per endpoint ($7.30/month per AZ) plus $0.01/GB processed.
That hourly fee makes them seem expensive compared to "free." Compare it to what they replace, though. NAT processing fees are $0.045/GB. Interface Endpoint processing fees are $0.01/GB. Each endpoint pays for itself if you move more than about 3-4 GB/month of traffic to that service.
The single highest-value Interface Endpoint for most architectures is ECR. Every container image pull from EKS, ECS, or any container platform pulling private images goes through ECR. A team running 100 container deployments per day with 500 MB images pulls 1.5 TB of ECR traffic per month. Through NAT, that's $67/month in processing fees alone. Through Interface Endpoints, it's about $22/month in endpoint hours plus $15 in processing. Savings: $30/month, and the hourly endpoint cost stays flat as ECR usage grows.
Other high-value Interface Endpoints to consider:
- Secrets Manager if your application fetches secrets on every request or per-pod.
- KMS if you use SSE-KMS heavily on S3 or RDS encryption.
- CloudWatch Logs if you ship logs to CloudWatch from private subnets.
- SSM if you use Session Manager or SSM Parameter Store from private compute.
Pattern: provision endpoints with a Terraform module
locals {
interface_endpoints = [
"ecr.api",
"ecr.dkr",
"secretsmanager",
"kms",
"logs",
"ssm",
]
}
resource "aws_vpc_endpoint" "interface" {
for_each = toset(local.interface_endpoints)
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.us-east-1.${each.value}"
vpc_endpoint_type = "Interface"
subnet_ids = aws_subnet.private[*].id
security_group_ids = [aws_security_group.endpoints.id]
private_dns_enabled = true
}Six endpoints across 3 AZs is $131/month in hourly fees plus processing. Compared to typical NAT processing for the same services (~$200-500/month), it's a clear win.
Alternative 3: NAT instances for small workloads
This isn't right for production with strict uptime requirements, but it's a great option for personal projects, dev environments, and small businesses.
A NAT instance is just an EC2 instance configured to forward IP packets and perform source NAT. Tools like fck-nat package this into a ready-to-run AMI. A single t4g.nano running fck-nat costs about $3/month plus negligible data transfer fees. Compare that to a NAT Gateway at $32/month base + $0.045/GB.
Trade-offs to be honest about:
- No automatic failover. If the NAT instance crashes, you need manual or scripted recovery. Auto Scaling Groups can rebuild it but there's a downtime window.
- Bandwidth limited by instance size. t4g.nano handles roughly 100 Mbps. For higher throughput, upsize.
- You own the patching. NAT instances are EC2 instances. They need OS updates, security patches, monitoring.
For a personal AWS account or a development VPC, none of these matter. For production with SLA commitments, stick with NAT Gateway (and the optimizations above).
Putting it together: a real cost comparison
Consider a typical mid-sized production VPC with:
- 3-AZ deployment
- 5 TB/month total NAT traffic (S3 reads, container pulls, external APIs)
- 2 TB/month of that is S3 traffic from private subnets
- 1 TB/month is ECR image pulls
- 2 TB/month is genuine external traffic (npm, GitHub, Stripe, etc.)
Without any optimization:
- 3 NAT Gateways: $98.55/month
- 5 TB processing: $225/month
- Total: $323.55/month
With S3 Gateway Endpoint + ECR Interface Endpoints in 3 AZs:
- 3 NAT Gateways: $98.55/month
- 2 TB external traffic through NAT: $90/month
- S3 traffic via Gateway Endpoint: $0
- ECR Interface Endpoints (2 endpoints × 3 AZs): $43.80/month base
- ECR traffic via endpoints: $10/month
- Total: $242.35/month
Savings: $81/month (25%), with no functional change. Add Secrets Manager and KMS endpoints if you use them heavily and savings climb further.
How to measure your current NAT cost
Before optimizing, you need to know where the bytes are going. AWS offers VPC Flow Logs and NAT Gateway metrics. The fastest way to triage:
- CloudWatch NAT Gateway metrics. The BytesOutToDestination and BytesInFromSource metrics tell you total traffic but not destinations.
- VPC Flow Logs. Enable on the private subnets and query in CloudWatch Insights or Athena. Group by destination IP and reverse-DNS to find the top bytes-consuming services.
- C3X cost recommendations. Run
c3x recommend --path .on your Terraform. It flags NAT-heavy patterns and suggests endpoint configurations.
For more on how C3X estimates NAT and helps surface optimization opportunities, start with the quickstart guide.
FAQ
How much does AWS NAT Gateway actually cost?
$0.045 per hour for the gateway to exist (about $32.85/month per NAT) plus $0.045 per GB of data processed in either direction. A 3-AZ deployment with 10 TB/month of traffic costs $98.55 in gateway hours plus $450 in data processing, totaling $548.55 per month.
Are VPC Gateway Endpoints for S3 really free?
Yes. VPC Gateway Endpoints for S3 and DynamoDB have no hourly fee and no data processing fee. Adding them takes 10 minutes of Terraform and eliminates NAT Gateway data processing fees for all S3 and DynamoDB traffic from private subnets.
When are Interface Endpoints cheaper than NAT for AWS services?
Roughly when you push more than 3-4 GB/month through that service. Each Interface Endpoint is $0.01/hour per AZ ($7.30/month per AZ) plus $0.01/GB processed. The crossover with NAT's $0.045/GB processing fee happens at very low volume for most workloads.
Can I use a NAT instance instead of NAT Gateway?
Yes, for small or non-critical workloads. A t4g.nano running fck-nat or similar costs about $3/month plus negligible data transfer. Not high-availability without manual failover, but acceptable for personal projects, dev environments, or any workload where occasional NAT downtime is acceptable.
What's the difference between Gateway Endpoints and Interface Endpoints?
Gateway Endpoints use route table modifications and are only available for S3 and DynamoDB. They're free. Interface Endpoints provision ENIs in each AZ using PrivateLink and work for hundreds of AWS services. They cost $0.01/hour per AZ plus $0.01/GB processed.
Why is NAT processing so expensive?
AWS charges the same per-GB rate for processing ($0.045/GB) as for the hourly rate. There's no technical reason it has to cost that much; it's a pricing decision. The processing fee is what makes NAT the second-largest AWS line item for many production workloads, behind only EC2.
What to do next
If your AWS bill has a meaningful NAT line item, the order of operations is:
- Add S3 and DynamoDB Gateway Endpoints today. They're free.
- Identify the top 3-5 AWS services your private subnets call. Add Interface Endpoints for those.
- Run C3X on your IaC to find any remaining NAT-heavy patterns.
- For non-production VPCs, evaluate whether a NAT instance is sufficient.
For step-by-step Terraform examples and concrete numbers, see the aws_nat_gateway and aws_vpc_endpoint catalog pages. If you want to run C3X on your own Terraform first, the quickstart gets you to a cost estimate in under five minutes.
Share this post
Try C3X on your own Terraform
Free and open source. No API key required. One command to install, one command to estimate.