Cutting NAT Gateway Costs: The Data Processing Fee Is the Real Bill
NAT Gateway has appeared here twice — as the top cause of sudden bill spikes and as a structural fixed cost on the standing checklist — but there was no dedicated post breaking down the bill and ordering the cuts. The conclusion up front: the real body of the NAT Gateway bill is the per-GB data processing fee, not the hourly rate, and the first move is not tuning NAT but routing traffic out of it. The gateway endpoints for S3 and DynamoDB are free, and plenty of accounts still don’t use them. Prices are for us-east-1.
The billing structure: three overlapping layers #
Traffic through a NAT Gateway can carry up to three kinds of charges:
| Layer | Rate | When it applies |
|---|---|---|
| Hourly | ~$0.045 (about $33/month) | As long as the gateway exists, per gateway per AZ |
| Data processing | ~$0.045/GB | Every byte through it, regardless of direction |
| Internet transfer | ~$0.09/GB (outbound) | Charged separately on traffic leaving to the internet |
Two things get missed. First, downloads are charged too. Inbound traffic from the internet carries no transfer fee, but the $0.045/GB NAT processing fee applies in full — so a private subnet pulling container images, packages, and datasets grows the bill all by itself. Second, outbound traffic stacks processing plus transfer charges to about $0.135/GB — 1.5x what the same byte costs when an instance in a public subnet sends it directly ($0.09). One hop makes the same byte half again as expensive.
The hourly fee looks small but multiplies. Following the availability rule of one gateway per AZ, a 3-AZ setup pays about $100 a month at zero traffic. Sharing one NAT across AZs saves the hourly fees but adds inter-AZ data transfer charges and turns that AZ’s failure into a full outbound outage — production keeps per-AZ placement as the default.
First priority: open the free bypasses #
- Gateway endpoints (S3, DynamoDB): free — no hourly, no per-GB. Adding the endpoint to the route table detours S3- and DynamoDB-bound traffic around NAT. For accounts moving backups, logs, and datasets from private subnets to S3, this one setting routinely erases the processing-fee line item. There is no reason not to set it; it is a literal free lunch.
- Interface endpoints (ECR, CloudWatch, SQS, and most AWS services): about $0.01 per AZ-hour plus $0.01/GB processed. That’s roughly a fifth of NAT’s $0.045/GB, so the busier the service, the bigger the win. The flagship case is ECR: image pulls for a frequently deploying cluster belong on an interface endpoint. But the hourly fixed fee is real — moving every trickle of traffic to an endpoint just adds fixed costs. Move services doing tens of GB a month or more first.
Second priority: options that change the structure #
- IPv6 + egress-only internet gateway: the outbound-only gateway for IPv6 traffic has no hourly or processing fees. The destination services must support IPv6 and you need dual-stack networking, so this is an item for new VPC designs.
- NAT instance: running NAT yourself on a small EC2 instance trades processing fees for instance fees. Bandwidth limits, patching, and failure handling all land on you, so it’s not a production recommendation — it fits a dev VPC where saving the $33+ a month matters. For dev environments, also consider skipping NAT entirely with a public-subnet layout.
- Regional NAT Gateway: the region-scoped mode added in late 2025, which removes the per-AZ gateway bookkeeping. For new designs it’s worth comparing against standard mode’s pricing, along with the billing option aimed at high-throughput workloads.
Diagnosis: know what crosses the NAT and how much #
Choosing what to cut requires an inventory of NAT traffic.
- Cost Explorer: watch the
NatGateway-Bytesusage type for volume trends. For spikes, the triage steps are exactly those in the dedicated post. - VPC Flow Logs: aggregate bytes by destination on the NAT’s ENI and the top culprits fall out. It’s usually S3, ECR, external APIs, and log shippers in that order — and the first two can be pulled out via endpoints immediately.
- Verify the drop: after adding endpoints, confirm
NatGateway-Bytesactually bent downward. A missed route table leaving some subnets on the NAT path is a common miss.
The order of cuts #
- Gateway endpoints first: unconditional for every VPC with S3- or DynamoDB-bound traffic. Free means no math required.
- Find the top culprits with Flow Logs: aggregate the remaining traffic by destination and move AWS services above tens of GB a month to interface endpoints.
- Judge external API traffic by the total: traffic that must reach the internet stays on NAT. If that share is large, work the architecture side — caching, batched transfers, in-region alternatives.
- Remove NAT from dev environments: a NAT instance or a public-subnet layout erases the monthly fixed cost.
- Recheck multi-AZ placement: per-AZ NAT stays the production default, but check that gateway placement matches where the traffic actually is, so inter-AZ fees aren’t leaking.
Summary #
- The body of the NAT Gateway bill is the processing fee ($0.045/GB). It applies to downloads too, and outbound stacks with transfer fees to 1.5x the direct path.
- Gateway endpoints for S3 and DynamoDB are free. One setting erases a whole line item — the highest-yield cut available.
- Move busy AWS services (ECR and friends) to interface endpoints ($0.01/GB). Mind the hourly fixed fee: migrating trickle traffic backfires.
- Cuts start with measurement: find the culprits via
NatGateway-Bytesand Flow Logs, then confirm the curve actually bent. - Consider removing NAT from dev VPCs entirely; in production, keep per-AZ placement and check it aligns with the traffic.