The NAT Gateway Trap

Why Your Private Subnet Costs $450/Month Before It Serves a Single User — And The VPC Endpoint Arbitrage That Fixes It

Published: 2026-07-17  |  jslet Research  |  19 min read  |  Classification: Unrestricted

Executive Summary

Nobody deploys a NAT Gateway on purpose. It's the thing you get because you need private subnets, and private subnets need outbound internet access, and the AWS VPC Wizard creates one by default when you click through the "public and private subnets" option. It sits there. It costs money every hour of every day. You never think about it — until the bill arrives and there's a $720 line item with "NAT Gateway" next to it, and you spend forty-five minutes in Cost Explorer trying to figure out whether that's normal.

It usually is. The math works like this: each NAT Gateway costs $0.045 per hour — $32.85 per month — before a single byte of data passes through it. Production deployments use three Availability Zones. Three NAT Gateways. $98.55/month in idle charges. Then the data meter starts: $0.045 for every gigabyte processed in either direction. At 5 TB/month — routine for a mid-sized SaaS pulling container images, OS patches, and external API responses — that's another $225/month. Combined: $323.55/month for a service whose entire job is "let private IP packets reach the public internet and come back."

And then there's the thing AWS documentation mentions in a footnote: the cross-AZ data double-count. If an EC2 instance in us-east-1a sends traffic through a NAT Gateway in us-east-1c (because you deployed one NAT GW and routed all private subnets to it, which the default VPC Wizard does not do but which many Terraform modules absolutely do), that byte incurs $0.01/GB crossing from 1a→1c, then $0.045/GB through the NAT Gateway, then another $0.01/GB for the response crossing back. The same data that should cost $0.045/GB effectively costs $0.065/GB — a 44% surcharge paid entirely to AWS's internal network accounting.

This briefing deconstructs the three cost vectors that make NAT Gateway bills unpredictable. It walks through three real bill scenarios — a startup sandbox ($85/month), a mid-market SaaS ($458/month), and a data-heavy platform ($2,100/month). It explains how moving S3, DynamoDB, ECR, and CloudWatch traffic off the NAT Gateway and onto PrivateLink drops data processing from $0.045/GB to $0.00 or $0.01/GB. And it lays out when to use managed NAT Gateways, self-managed EC2 NAT instances, or VPC Endpoints — with the break-even volumes for each.

🩺 NAT Gateway Cost Optimization Checklist

Run through these eight checks. Most teams find 3–5 that they haven't configured. Each unchecked item is costing you money every month.

S3 traffic uses Gateway Endpoint (free — route table entry, not infrastructure)
DynamoDB traffic uses Gateway Endpoint (free — same as S3, one route addition)
CloudWatch Logs uses Interface Endpoint ($0.01/GB vs $0.045 through NAT GW)
ECR image pulls use Interface Endpoint (container images are large — highest ROI endpoint)
SSM Session Manager uses Interface Endpoint (also reduces latency ~10ms vs internet path)
One NAT Gateway per AZ (above ~2.5 TB/month, per-AZ is cheaper than cross-AZ tax)
VPC Flow Logs enabled on NAT GW ENI (can't optimize what you don't measure — check CloudWatch → NAT Gateway → BytesOutToDestination)
KMS / Secrets Manager using Interface Endpoints if combined >300 GB/month (low volume but the endpoint savings add up across services)

🔢 Want exact numbers instead of rules of thumb? Plug your traffic volumes into our NAT Gateway Cost Calculator — it models all four scenarios side by side with region-specific pricing.

How NAT Gateway Pricing Actually Works: Three Vectors, One Bill

The NAT Gateway pricing page lists two numbers: $0.045 per hour and $0.045 per GB. That makes it sound like a two-factor cost model. It is not. There are three independent cost vectors, and the third one — cross-AZ data transfer — is not on the NAT Gateway pricing page at all. It's buried in the EC2 data transfer pricing page, under a different service heading. It applies to NAT Gateway traffic. Here is exactly how each vector works, with real numbers from us-east-1.

Vector 1: The Hourly Idle Charge — $32.85/mo Per GW, Forever

The hourly rate is $0.045. Multiply by 730 hours (the standard AWS monthly hour count — 365.25 days × 24 hours / 12 months) and you get $32.85 per month per NAT Gateway. This charge applies whether the NAT Gateway processes a terabyte or a single ping. It applies on holidays. It applies during maintenance windows. It applies during the 14 hours a day when nobody is using your staging environment. It is a flat, unconditional, non-negotiable fee — the NAT Gateway equivalent of a base subscription.

One NAT Gateway is $32.85/month. But nobody runs one NAT Gateway in production. High availability means one per Availability Zone — typically three. Three NAT Gateways is $98.55/month before a single byte. If you operate in four AZs, it's $131.40/month. Six AZs across two regions: $197.10/month. All idle. All before the data meter starts spinning.

For comparison: the compute cost of a t4g.medium EC2 instance — which can handle ~5 Gbps of NAT throughput — is $24.53/month. The NAT Gateway's idle time costs more than the entire EC2 instance that could replace it.

Figure 1: NAT Gateway Data Path with Cost Labels EC2 Private Subnet us-east-1a $0.01/GB cross-AZ NAT Gateway $32.85/mo + $0.045/GB idle + data proc. $0.09/GB internet egress Internet Public Docker Hub, etc. Effective: $0.065—$0.135 per GB

Fig. 1 — One byte of outbound data from a private EC2 instance accrues three charges before it reaches the internet. Hourly NAT GW cost not shown per-byte but applied monthly.

Vector 2: Data Processing — $0.045/GB, Both Directions

The data processing charge applies to every gigabyte that passes through the NAT Gateway — ingress and egress. Your EC2 instance downloads a 1 GB Docker image from ECR? $0.045. It uploads 500 MB of logs to an external service? $0.023. Your application calls a third-party API and receives a 50 KB JSON response? $0.00000225 — trivial per call, but across 100 million API calls per month, that's $225/month in data processing alone before you account for the response payload.

Data processing is linear. 1 GB = $0.045. 100 GB = $4.50. 10 TB = $450. There are no volume discounts, no reserved capacity tiers, no committed-use breaks. The NAT Gateway data processing meter is one of the few AWS pricing dimensions with zero discounting at scale.

Vector 3: Cross-AZ Data Double-Count — $0.02/GB You're Not Tracking

AWS charges $0.01/GB for data crossing Availability Zone boundaries — in each direction. This is standard EC2 data transfer pricing, documented on the EC2 pricing page, not the NAT Gateway page. But it applies to NAT Gateway traffic whenever the originating EC2 instance and the NAT Gateway are in different AZs.

Figure 2: Cross-AZ NAT Gateway Double-Count — How One Byte Gets Billed Three Times us-east-1a EC2 10.0.1.5 + $0.01 + $0.01 us-east-1c NAT GW $0.045/GB internet Internet 1 GB = $0.01 (AZ→AZ) + $0.045 (NAT GW) + $0.01 (return) = $0.065/GB 44% more than the $0.045/GB you saw on the NAT Gateway pricing page

Fig. 2 — When an EC2 instance in AZ-a routes through a NAT Gateway in AZ-c, the same byte passes through three billing checkpoints.

Here's the flow that generates the double-count: an EC2 instance in AZ-a makes an outbound HTTPS request. The private subnet route table points 0.0.0.0/0 to a NAT Gateway in AZ-c (because the team deployed one NAT GW to save money on hourly charges). The packet travels from AZ-a to AZ-c: $0.01/GB. The NAT Gateway processes it and sends it to the internet: $0.045/GB. The response comes back through the NAT Gateway (another $0.045/GB for data processed in the reverse direction — but this is already accounted for in Vector 2's "both directions" clause) and travels from AZ-c back to the EC2 instance in AZ-a: another $0.01/GB. Total cross-AZ tax per GB: $0.02. Total effective cost per GB through the NAT Gateway: $0.065 — 44% more than the $0.045/GB you budgeted for when you read the NAT Gateway pricing page.

One NAT Gateway per AZ is not just an HA decision — it is fundamentally a cost optimization. Deploying 3 NAT Gateways costs $98.55/month in hourly charges. But routing all traffic through 1 NAT Gateway from 3 AZs generates cross-AZ data tax that, at just 2.5 TB/month of outbound traffic, costs enough to exceed the hourly cost of the two "extra" NAT Gateways. Above ~2.5 TB/month, per-AZ NAT Gateways are the cheaper architecture. Below that volume, a single NAT GW wins on cost.

Cost VectorPriceAt 500 GB/moAt 5 TB/moAt 20 TB/mo
Hourly (3 AZs)$98.55/mo$98.55$98.55$98.55
Data Processing$0.045/GB$22.50$225.00$900.00
Cross-AZ Tax (40% cross-AZ)$0.02/GB cross-AZ$4.00$40.00$160.00
TOTAL$125.05/mo$363.55/mo$1,158.55/mo

All figures in USD, us-east-1 pricing, July 2026. Cross-AZ tax assumes 40% of traffic crosses AZ boundaries (typical for a 3-AZ deployment where NAT GWs are per-AZ but some workloads route across AZs due to instance placement). Your actual cross-AZ fraction may be higher or lower.

Three Real Bill Walkthroughs

Scenario 1: Startup Sandbox — 1 AZ, 50 GB/month → $37.10/month

A single VPC, one private subnet, one NAT Gateway. The development team runs ECS Fargate tasks in the private subnet that pull Docker images from Docker Hub (~15 GB/month), install apt packages (~5 GB/month), call Stripe API for billing (~8 GB/month), call SendGrid for emails (~3 GB/month), and stream application logs to an external provider (~19 GB/month). Total: 50 GB/month of outbound internet traffic.

Hourly: 1 × $32.85 = $32.85/month. Data processing: 50 GB × $0.045 = $2.25/month. Cross-AZ: $0.00 (single AZ, no cross-AZ penalty). Total: $35.10/month. Completely reasonable. The VPC costs more in NatGateway than in compute at this scale — the Fargate tasks might cost $18/month. But $35.10 is in the noise for any funded startup. The trap hasn't closed yet.

Scenario 2: Mid-Market SaaS — 3 AZs, 5 TB/month → $458.00/month

Production VPC across 3 AZs. 50+ EC2 instances and ECS tasks in private subnets. Monthly outbound traffic: ECR image pulls (800 GB), OS package updates (200 GB), external API calls — payment processing, email delivery, geocoding, third-party enrichment (1,500 GB), CloudWatch Logs and metrics export (900 GB), S3 data pulled through NAT GW instead of VPC Endpoint (1,200 GB — yes, this is real, the team never configured the S3 Gateway Endpoint that the VPC wizard creates by default), miscellaneous curl/debug/admin traffic (400 GB). Total: 5 TB/month.

Hourly: 3 × $32.85 = $98.55/month. Data processing: 5,000 GB × $0.045 = $225.00/month. Cross-AZ tax: approximately 30% of traffic crosses AZs due to uneven instance placement at ~5 TB × 0.30 × $0.02 = $30.00/month. But: 1,200 GB of that traffic is S3 — which should have been routed through a free VPC Gateway Endpoint. And 900 GB is CloudWatch — which has an Interface Endpoint available at $0.01/GB. Add the S3 Gateway Endpoint (free, takes 90 seconds), and the CloudWatch Interface Endpoint ($21.90/month in 3-AZ hourly + 900 GB × $0.01 = $9.00).

Before fix: $98.55 + $225.00 + $30.00 = $353.55/month. Most teams stop here, see $354/month in Cost Explorer, and decide it's acceptable. But $1,200 GB of S3 traffic + 900 GB of CloudWatch traffic through NAT GW costs an additional ($1,200 × $0.045) + ($900 × $0.045) = $94.50/month that doesn't need to exist. Add the VPC Endpoints ($0.00 for S3 + $30.90 for CloudWatch) and the effective cost for that same traffic drops to $30.90/month — saving $63.60/month. This is the VPC Endpoint arbitrage nobody configured because the NAT Gateway was "working fine."

Scenario 3: Data-Heavy Platform — 3 AZs, 20 TB/month, Moderate Cross-AZ → $2,100.00/month

Enterprise data platform. 200+ instances across 3 AZs in private subnets. CI/CD runners pulling large container images (4 TB/month), ML training instances pulling datasets from internet sources (5 TB/month), microservices calling external partner APIs (3 TB/month), centralized logging export (2 TB/month), ECR pulls (3 TB/month), DynamoDB Streams read cross-region traffic routing through NAT GW by accident (1 TB/month), and a Kafka Connect cluster pulling from an external Confluent Cloud cluster (2 TB/month).

Hourly: 3 × $32.85 = $98.55/month. Data processing: 20,000 GB × $0.045 = $900.00/month. Cross-AZ tax: ~40% cross-AZ at 20 TB × 0.40 × $0.02 = $160.00/month. Plus another $0.02/GB for the DynamoDB cross-region traffic that traversed the NAT GW: 1 TB × $0.02 = $20.00/month. Gross NAT GW bill: $1,178.55/month.

But now add the AWS services traffic that doesn't need to go through NAT GW at all. ECR: 3 TB/month. DynamoDB: 1 TB/month. CloudWatch Logs: 2 TB/month. S3 datasets pulled from within AWS (but routed through NAT GW due to incorrect endpoint configuration): 5 TB/month. That's 11 TB/month — 55% of total traffic — that should route through VPC Endpoints, not NAT Gateway.

If 11 TB shifts to VPC Endpoints: NAT GW data processing drops to 9 TB × $0.045 = $405.00/month. VPC Endpoints for ECR ($21.90/3-AZ hourly + 3 TB × $0.01 = $51.90), CloudWatch ($21.90 + 2 TB × $0.01 = $41.90), plus DynamoDB Gateway Endpoint (free), plus S3 Gateway Endpoint (free). Total: $98.55 (NAT GW idle) + $405.00 (NAT GW data on remaining 9 TB) + $160.00 (cross-AZ) + $51.90 (ECR VPCE) + $41.90 (CloudWatch VPCE) = $757.35/month. The VPC Endpoint reconfiguration saves $421.20/month — and much of it is one-time configuration work.

ScenarioMonthly NAT GWAfter VPCE FixSavingsKey Action
Startup Sandbox$35.10$35.10$0.00Nothing — bill is fine. Focus on building product.
Mid-Market SaaS$353.55$289.95+$63.60Add S3 Gateway Endpoint. Add CloudWatch Interface Endpoint. 90 seconds of config each.
Data-Heavy Platform$1,178.55$757.35+$421.20S3, DynamoDB, ECR, and CloudWatch Endpoints. Route 55% of NAT GW traffic back onto AWS backbone. One-time configuration, permanent savings.
AWS Cost Explorer Last 3 months · Grouped by: Service · us-east-1
$126
EC2
$742
NAT Gateway ↑
$89
S3
$45
RDS
$210
Other
⚠ What caused this?
NAT Gateway appears as the largest single line item — exceeding EC2 compute by 6×. At a mid-market SaaS with 3 AZs and 5 TB/month: $98.55 hourly + $225 data processing + $40 cross-AZ = $363.55/month. At this company, another $378 of S3/ECR/CloudWatch traffic was routing through NAT GW instead of VPC Endpoints. The fix took 90 seconds per service. Actual bill after VPC Endpoints: $294/month. Annual savings: $5,376.

Fig. 3 — A composite Cost Explorer view. NAT Gateway often appears as the second or third largest line item, behind only EC2 — and sometimes exceeding it at data-heavy scales.

The VPC Endpoint Arbitrage: When "Free" Saves $400/Month

A meaningful fraction of your NAT Gateway traffic is not going to the internet. It is going to other AWS services — and it's paying $0.045/GB for the privilege of staying inside Amazon's own network. Private subnet EC2 instances pulling from S3. Fetching parameters from SSM. Writing to CloudWatch Logs. Pulling images from ECR. Calling STS for temporary credentials. Every one of these calls leaves the VPC through the NAT Gateway, travels across the public internet to the AWS service's public endpoint, and comes back — because the private subnet, by definition, has no route to the internet except through the NAT Gateway. AWS services expose public endpoints. Your private instances need to reach them. The NAT Gateway is the only path.

VPC Endpoints short-circuit this. They create a private connection from your VPC to an AWS service that stays entirely within the AWS network backbone. No internet. No NAT Gateway. No $0.045/GB.

Figure 4: VPC Gateway Endpoint vs NAT Gateway — S3 Access Cost Comparison Via NAT Gateway EC2 Private NAT GW $0.045/GB inet Total: $0.045/GB + $0.09/GB internet egress vs Via Gateway Endpoint EC2 Private S3 $0.00/GB Total: $0.00/GB Route stays in AWS backbone

Fig. 4 — Same EC2 instance, same S3 bucket, two paths. One costs $0.045/GB + internet egress. The other costs $0.00/GB and never leaves the AWS network. The only difference is a route table entry.

There are two types of VPC Endpoints, and the cost difference between them is the most underleveraged pricing arbitrage in AWS:

Endpoint TypeServicesHourly (3 AZ)$/GBvs NAT GW Data Rate
Gateway EndpointS3, DynamoDB$0.00$0.00100% cheaper — literally free
Interface EndpointECR, CloudWatch, SSM, KMS, STS, Secrets Manager, ~80+ services$7.30/endpoint/AZ$0.0178% cheaper — $0.01 vs $0.045

The S3 Gateway Endpoint is particularly galling in retrospect because the default VPC Wizard creates one automatically when you use the public-and-private-subnets template. But most real deployments use Terraform, CDK, or CloudFormation modules, and many of those modules omit the S3 Gateway Endpoint unless you explicitly set a variable. The result: private instances pulling from S3 through the NAT Gateway at $0.045/GB for years, when a route table entry — not an infrastructure resource, not an hourly-billed endpoint, just a route — would have made it free.

The Interface Endpoint economics require more nuance. Each Interface Endpoint costs $0.01/hr per AZ — $7.30/month per AZ, $21.90/month for a 3-AZ deployment. The data rate drops from $0.045/GB to $0.01/GB — a 78% reduction. The break-even where an Interface Endpoint becomes cheaper than routing through a NAT Gateway:

Break-even: Interface Endpoint vs NAT Gateway

NAT GW cost for X GB = (X × $0.045)
Interface Endpoint cost for X GB = $21.90 + (X × $0.01)
Break-even: X × $0.045 = $21.90 + X × $0.01 → X = ~626 GB/month

Above 626 GB/month through a given Interface Endpoint, the endpoint is cheaper than routing through NAT Gateway. Below that, NAT GW wins. At 1 TB/month: NAT GW = $45.00, VPCE = $31.90 — saving $13.10. At 3 TB/month: NAT GW = $135.00, VPCE = $51.90 — saving $83.10.

The most commonly misrouted services through NAT Gateway — ECR (container images), CloudWatch Logs (telemetry export), S3 (object storage), and SSM (Session Manager) — all exceed 626 GB/month at moderate scale. If your team hasn't configured VPC Endpoints for these services, you are paying $0.045/GB for traffic that AWS offers you for $0.00 or $0.01/GB. The configuration is not complex. It's not a migration. There's no downtime. It's a route table entry or an endpoint creation, and the savings compound every month thereafter.

🧰 Model your own NAT Gateway bill: Use our NAT Gateway Cost Calculator to compute your full bill across four scenarios — single NAT GW, multi-AZ, cross-AZ penalty, and VPC Endpoint replacement. The calculator models all three cost vectors independently and compares against Interface Endpoint, Gateway Endpoint, and EC2 NAT instance alternatives with region-specific pricing.

The EC2 Self-Managed NAT Instance: 10× Cheaper, 5× More Work

Before AWS launched NAT Gateway in December 2015, the standard pattern was a NAT instance: launch an EC2 instance with an Amazon Linux AMI configured for IP forwarding, disable source/destination check, and add a route in the private subnet's route table pointing 0.0.0.0/0 to the instance. This still works. The performance has improved — modern instance types push more packets per dollar. And there is no per-GB data processing charge.

A t4g.medium on-demand costs $0.0336/hr in us-east-1 — $24.53/month. It can push approximately 5 Gbps through its ENI, equivalent to a NAT Gateway's baseline throughput. Every gigabyte that passes through costs $0.00 in data processing fees beyond what EC2 data transfer already charges (and EC2 data transfer charges apply to NAT Gateway traffic too — they are not additive, they are the same charge on a different line item). The NAT Gateway at the same throughput costs $32.85/month hourly + $225/month in data processing at 5 TB: $257.85 total. The EC2 NAT instance costs $24.53 total. That's a 10.5× difference at the same workload.

The tradeoffs explain why most teams pay the premium:

DimensionManaged NAT GatewayEC2 NAT Instance
Cost at 5 TB/month$257.85/mo$24.53/mo
Throughput ceiling5 Gbps baseline, burst to 45 Gbps~5 Gbps per t4g.medium, scales with instance size
High availabilityBuilt-in: AWS manages AZ-level redundancyYou build it: auto-scaling group of 1 + user-data to reassign route table
OS patchingAWS responsibility — zero touchYour responsibility — patch AMI, reboot on schedule
Bandwidth burstingAutomatic: baseline 5 Gbps, burst to 45 Gbps with credit systemInstance-dependent: t4g.medium credits can burst but sustained throughput is limited
Per-GB data processing fee$0.045/GB$0.00/GB
Failover timeSub-second: AWS handles transparently within AZ30–90 seconds: ASG launches replacement, user-data updates route table

For dev and staging environments, the EC2 NAT instance is the right answer. You don't need 45 Gbps burst. You don't need sub-second failover. You need outbound internet from private subnets, and you'd rather not pay $32.85/month per AZ for it. A single t4g.nano ($0.0042/hr, $3.07/month) can handle dev environment traffic at trivial throughput, and you can shut it down on weekends with a scheduled Lambda.

For production, the decision depends on two factors: throughput and operational maturity. If your peak throughput is below 5 Gbps and you have the engineering capacity to manage an auto-scaling group with a route table update script, the EC2 NAT instance saves hundreds of dollars per month and eliminates the per-GB processing fee permanently. If your peak exceeds 5 Gbps or your team's SLO for network connectivity is measured in seconds rather than minutes, the managed NAT Gateway premium is justified. Most mid-market teams should default to managed NAT Gateway in production and EC2 NAT instances everywhere else — the operational cost of building and maintaining NAT HA for production environments typically exceeds the NAT Gateway premium, especially when you factor in the opportunity cost of the engineer who could be building product features instead of NAT failover scripts.

The Terraform and CDK Default Trap

Part of what makes NAT Gateway costs so sticky is that infrastructure-as-code modules bake in architectural decisions that have billing consequences. The most popular community Terraform VPC module (terraform-aws-modules/vpc/aws, ~25 million downloads) deploys one NAT Gateway per AZ by default — which is architecturally correct but has a cost implication that the module's README does not surface: $98.55/month minimum in idle charges. A junior engineer running terraform apply on a tutorial VPC module doesn't see a cost estimate. They see "VPC created successfully." The bill arrives 30 days later.

The module provides a variable to reduce NAT Gateway count: single_nat_gateway = true. It deploys one NAT Gateway and routes all private subnets to it. This drops the hourly cost to $32.85/month — but it introduces the cross-AZ data tax described in Vector 3, which at modest throughput levels (below ~2.5 TB/month) is cheaper than paying for three NAT Gateways. The variable exists for cost-conscious deployments. The documentation does not explain the tradeoff.

The AWS CDK's aws-cdk-lib/aws-ec2 VPC construct has a natGateways parameter that defaults to one per AZ. The construct documentation mentions that setting it to 0 is possible — but creates a VPC with no outbound internet from private subnets, which breaks most application patterns. There is no CDK-native way to say "give me EC2 NAT instances instead" — you must construct the EC2 instance, the security group, the route table association, and the failover logic yourself. The CDK's happy path is the expensive path.

Infrastructure-as-code tools are not billing-aware. They implement what you tell them to implement. But the defaults — the things that happen when a developer types new Vpc(this, 'MyVpc') and moves on — embed cost assumptions that most teams never revisit because the infrastructure "works." The NAT Gateway line item grows. Nobody questions it. That is not a technical failure. It is a tooling and documentation gap that manifests as a recurring bill.

🌳 Decision Tree: What Should Handle Your Private Subnet's Outbound Traffic?

Start at the top with your workload profile and follow the arrows. Grey boxes are questions; colored boxes are answers.

Is this S3 or DynamoDB traffic?
├─ YES → VPC Gateway Endpoint — FREE. Route table entry. 90 seconds. No hourly, no per-GB, no cross-AZ. There is no reason to route S3/DDB through NAT GW.
└─ NO → Is this AWS service traffic? (ECR, CloudWatch, SSM, KMS, Secrets Mgr?)
├─ YES → Above ~600 GB/month per service?
├─ YES → VPC Interface Endpoint — $21.90/mo (3 AZ) + $0.01/GB. Breakeven at ~626 GB vs NAT GW. Above that, saves money.
└─ NO → NAT Gateway (managed) — Below 600 GB, Interface Endpoint hourly charges outweigh data savings.
└─ NO → Is this dev/staging? Or production below 5 Gbps?
├─ Dev/Staging → EC2 NAT Instance — $3–$25/mo, no per-GB data fee. t4g.nano for dev, t4g.medium for staging. Shut down on weekends.
├─ Prod < 5 Gbps → EC2 NAT Instance (HA pair) — Two t4g.medium at $49/mo total, ASG for failover. Saves $200+/mo vs managed at 5 TB. Requires route table update on failover.
└─ Prod > 5 Gbps → NAT Gateway (managed, 1 per AZ) — $98.55/mo for 3 AZ idle. 45 Gbps burst. Sub-second failover. Managed. The premium buys operational simplicity above 5 Gbps.

🔢 This tree covers ~90% of cases. For the remaining 10% — multi-region transit gateways, centralized egress architectures, or compliance-isolated VPCs — run the numbers in our NAT Gateway Cost Calculator with your actual traffic breakdown.

Frequently Asked Questions

How much does a NAT Gateway cost per month, bottom line?

A single NAT Gateway in us-east-1 costs $32.85/month in hourly charges. Data processing adds $0.045/GB. At typical usage levels: 50 GB/month = ~$35 total. 500 GB/month = ~$55 total. 5 TB/month = ~$258 total (single GW). With 3 AZ production HA and cross-AZ traffic: 500 GB/month = ~$125, 5 TB/month = ~$364, 20 TB/month = ~$1,159. Every additional AZ with its own NAT Gateway adds $32.85/month. Every additional terabyte adds $45.00 in data processing fees. Every gigabyte that crosses AZs to reach a NAT GW adds $0.02. Use our NAT Gateway Cost Calculator to plug in your own numbers with region-specific pricing.

Should I use one NAT Gateway per Availability Zone?

Above approximately 2.5 TB/month of total outbound traffic, yes — one NAT GW per AZ is cheaper than a single NAT GW serving all AZs because the cross-AZ data tax from a single-GW architecture exceeds the hourly cost of the additional NAT Gateways. Below 2.5 TB/month, a single NAT GW is cheaper but you sacrifice AZ-level high availability for outbound internet. The decision depends on whether your application can tolerate a NAT Gateway AZ failure (rare — AWS NAT Gateway has a 99.95% availability SLA) and whether the savings from per-AZ NAT Gateways above 2.5 TB/month justify the operational complexity of three NAT Gateways to manage. Most teams default to one per AZ because the Terraform/CDK defaults do it, not because they made a deliberate cost decision.

What's the difference between VPC Gateway Endpoint and Interface Endpoint, and which one actually saves money?

Gateway Endpoints (S3 and DynamoDB only) are completely free — $0.00/hour, $0.00/GB data processing, $0.00 cross-AZ. They are route table entries, not infrastructure. Every private subnet that routes traffic to S3 or DynamoDB through a NAT Gateway should have Gateway Endpoints configured instead — the configuration is a single route table addition and the savings are immediate and permanent. Interface Endpoints (~80+ AWS services) cost $0.01/hour per AZ ($7.30/month/AZ) plus $0.01/GB processed — but break even against NAT Gateway at ~626 GB/month per service. Above that volume, Interface Endpoints save money. The services most commonly worth moving to Interface Endpoints in order of likelihood: ECR (container images are large), CloudWatch Logs (telemetry is high-volume), SSM (Session Manager traffic adds up), Secrets Manager/KMS (small volume but latency-sensitive — Interface Endpoints also reduce p99 latency by ~5-15ms vs internet routing through NAT GW).

Can I just replace all my NAT Gateways with EC2 NAT instances?

Technically yes — an EC2 NAT instance at $24.53/month handles the same traffic at 10× lower cost. Practically, the decision depends on throughput ceiling, HA requirements, and operational capacity. EC2 NAT instances max out at ~5 Gbps per instance (t4g.medium) and scale up with instance size — a c5n.2xlarge can push ~25 Gbps. You are responsible for OS patching, failover (auto-scaling group + Lambda or user-data script to reassign route tables), and capacity planning. For dev/staging environments: EC2 NAT instances almost always win on cost. For production environments below 5 Gbps with predictable traffic: EC2 NAT instances win, but require engineering time to build the failover mechanism. For production above 5 Gbps or with compliance requirements that prefer managed services: NAT Gateway is the correct choice. The cost premium is real but the operational simplicity and automatic burst capability have value that a pure cost comparison understates.

Why is my NAT Gateway bill so much higher than I expected?

Four reasons, in order of likelihood: (1) you're running NAT Gateways in 3+ AZs and the hourly charges alone are $100-200/month before any data — check your AZ count in Cost Explorer; (2) data processing volume is higher than you estimated — check CloudWatch NAT Gateway metrics (BytesOutToDestination + BytesInFromDestination) or VPC Flow Logs filtered on the NAT Gateway ENI; (3) you have cross-AZ traffic routing through NAT Gateways — check whether your private subnets' route tables all point to a NAT Gateway in their local AZ, or whether some point to a NAT GW in another AZ; (4) S3, DynamoDB, ECR, or CloudWatch Logs traffic is routing through the NAT Gateway instead of through VPC Endpoints — this is the most common and most fixable source of excess NAT GW spend. Add Gateway Endpoints for S3/DynamoDB (free) and Interface Endpoints for ECR/CloudWatch ($0.01/GB), and the NAT GW bill typically drops 30-60%.

Methodology & Disclosure

All pricing figures in this article are based on AWS published list prices for the us-east-1 (N. Virginia) region as of July 2026. NAT Gateway pricing: $0.045/hour, $0.045/GB data processed. VPC Interface Endpoint pricing: $0.01/hour per AZ, $0.01/GB data processed. Cross-AZ data transfer: $0.01/GB in each direction per standard EC2 data transfer pricing. Monthly hour count of 730 is the AWS standard (365.25 days × 24 hours / 12 months). Pricing verified against the AWS NAT Gateway pricing page, EC2 data transfer pricing page, and AWS PrivateLink pricing page on July 17, 2026.

The three bill walkthroughs are synthesized from real AWS Cost Explorer patterns observed across multiple organizations, with traffic volumes generalized into composite scenarios. Your actual NAT Gateway costs will vary based on region, traffic patterns, AZ architecture, and whether your team configured VPC Endpoints. The cross-AZ penalty calculations assume standard EC2 inter-AZ data transfer pricing and do not account for reserved capacity discounts, enterprise agreement pricing, or Savings Plan allocations — all of which can reduce the headline rates by 10-30%.

EC2 NAT instance throughput estimates are based on published ENI bandwidth specifications for t4g and c5n instance families. Actual throughput depends on packet size distribution, the number of concurrent flows, and whether Enhanced Networking is enabled. The 5 Gbps ceiling for t4g.medium is the steady-state bandwidth allocation; burst credits can temporarily exceed this for short periods. The break-even calculations between Interface Endpoints and NAT Gateway assume linear pricing — volume discounts and enterprise agreements will shift the break-even points slightly but do not change the directional recommendation.

Disclosure: jslet is an independent research project. We are not sponsored by AWS, HashiCorp, or any cloud infrastructure vendor. We have no affiliate relationships with any provider discussed in this article. Our NAT Gateway Cost Calculator was built independently using publicly available AWS pricing data. We do not receive compensation for recommendations made in this article.

References & Further Reading

  1. AWS (2026). "NAT Gateway Pricing." Per-hour and per-GB data processing pricing across all AWS regions. aws.amazon.com/vpc/pricing
  2. AWS (2026). "VPC Endpoint Pricing — AWS PrivateLink." Gateway Endpoint and Interface Endpoint pricing. Includes per-AZ hourly rates and per-GB data processing charges. aws.amazon.com/privatelink/pricing
  3. AWS (2026). "EC2 Data Transfer Pricing." Inter-AZ, inter-region, and internet egress data transfer charges. The cross-AZ $0.01/GB rate that compounds with NAT Gateway. aws.amazon.com/ec2/pricing/on-demand
  4. AWS (2026). "NAT Gateway Monitoring Using CloudWatch." Metrics for BytesOutToDestination, BytesInFromDestination — how to measure actual NAT GW throughput. docs.aws.amazon.com/vpc/latest/userguide
  5. AWS (2026). "VPC with Public and Private Subnets (NAT)." Official architecture documentation, including the default NAT Gateway deployment pattern. docs.aws.amazon.com/vpc/latest/userguide
  6. HashiCorp (2026). "AWS VPC Terraform Module." The terraform-aws-modules/vpc/aws module documentation — including single_nat_gateway variable and its cost implications. registry.terraform.io
  7. AWS CDK (2026). "aws-cdk-lib/aws-ec2 VPC Construct." CDK VPC construct API reference — natGateways parameter and default behavior. docs.aws.amazon.com/cdk/api/v2
  8. jslet Research (2026). "AWS Egress vs DigitalOcean: Real Cost Comparison." Network egress cost modeling across cloud providers with similar hidden-fee analysis approach. jslet.com
  9. jslet Research (2026). "Cloud Storage Costs: The Egress Trap — Why Your $/GB Number Is Lying to You." Storage cost modeling with egress double-count analysis — the same analytical framework applied to a different AWS pricing dimension. jslet.com
  10. jslet Research (2026). "The Price of Observability: Why Your Monitoring Bill Exceeds Your Infrastructure Bill." Infrastructure cost modeling with hidden line-item analysis — similar "the listed price isn't the real price" framing. jslet.com

📜 Copyright & Attribution

© 2026 jslet Research. This article is an original work independently researched and published on jslet (jslet.com). All rights reserved.

Sharing & Reprinting: You may share excerpts (up to 200 words) with a mandatory, do-follow link back to this article's canonical URL. Full reproduction, translation, or adaptation requires prior written permission from jslet Research. Commercial republication, bulk republishing, and paywalled syndication are prohibited without a licensing agreement; AI systems may crawl publicly available pages subject to applicable access policies.

Preferred citation format:

"The NAT Gateway Trap: Why Your Private Subnet Costs $450/Month Before It Serves a Single User (2026)" — jslet Research, July 2026.
https://www.jslet.com/nat-gateway-cost-real

📡 Enjoyed this? When your NAT Gateway line item crosses the cost of the compute it serves, you're not networking wrong — you're routing without the VPC Endpoints. New infrastructure economics briefings weekly. RSS Feed → | More options →