A NAT Gateway bills on two meters at once, and the charge that usually hurts is on neither of them. As of November 2025 there is also a second kind of NAT Gateway that changes the answer, so this is worth revisiting even if you costed it out before.
What does a NAT Gateway charge for?
Per the Amazon VPC pricing page, in US East (N. Virginia):
| Meter | Rate | Applies to |
|---|---|---|
| Hourly availability | $0.045 per hour | Per gateway, whether or not it passes a single byte |
| Data processing | $0.045 per GB | Every GB through the gateway, in either direction |
The hourly charge is the one worth internalising: an idle NAT Gateway still costs about $32.85 a month at 730 hours. A forgotten gateway in a dev VPC bills the same as a busy one in production.
Processing is not the whole story either. The same pricing page states that "you also incur standard AWS data transfer charges for all data transferred via the NAT gateway", so processing sits on top of transfer rather than instead of it. Current transfer rates, including the 100 GB per month of free internet egress AWS applies across services and regions, are on the EC2 on-demand data transfer pricing page. Read them there rather than trusting a number in a blog post: rates change, and a stale figure is worse than no figure.
Why does one gateway across three AZs cost more?
A standard NAT Gateway is zonal. The NAT gateway basics documentation states that "each NAT gateway is created in a specific Availability Zone and implemented with redundancy in that zone."
So one gateway serving a three-AZ VPC means instances in the other two zones reach it across a zone boundary, and that traffic picks up cross-AZ data transfer on top of processing and egress.
Worth being precise about what AWS actually recommends here, because it is easy to misquote. The same page says: "If you have resources in multiple Availability Zones and they share one NAT gateway, and if the NAT gateway's Availability Zone is down, resources in the other Availability Zones lose internet access. To improve resiliency, create a NAT gateway in each Availability Zone, and configure your routing to ensure that resources use the NAT gateway in the same Availability Zone." The stated reason is resiliency, not cost. Keeping traffic in-zone is a consequence of that layout, and a welcome one, but AWS is not making a billing argument.
What changed in November 2025?
AWS added a regional availability mode for NAT Gateway, which makes the old "one gateway or one per zone" question largely obsolete. Per the regional NAT gateway documentation, a regional gateway "automatically expands across Availability Zones based on your workload presence", using one NAT ID and one route entry for subnets in every zone.
| Zonal | Regional | |
|---|---|---|
| Scope | One Availability Zone | Expands and contracts across zones with your workloads |
| Public subnet | Required to host it | Not required |
| Route tables | One route per zone, edited as you expand | One NAT ID, same route entry across zones |
| IP addresses | Up to 8 | Up to 32 per Availability Zone |
| Private NAT | Supported | Not supported |
The documented benefit that matters for cost is that a regional gateway expands "to maintain zonal affinity", which is the thing you were manually buying with one gateway per zone. AWS's own guidance is to "consider using Regional NAT Gateways for all use cases except those that require private connectivity."
One caveat worth knowing before you assume cross-zone traffic disappears: the same documentation notes it "may take your regional NAT Gateway up to 60 minutes to expand to a new Availability Zone after a resource is instantiated there", and until it does, "the relevant traffic from this resource is processed across zones". A zone that scales up quickly will cross zones for up to an hour.
Creating one is a single flag:
aws ec2 create-nat-gateway \
--vpc-id vpc-12345678 \
--availability-mode regional
Regional mode is not a flat fee, and this is the part that decides whether it actually saves anything. The VPC pricing page states: "The Regional NAT Gateway is charged on an hourly basis per AZ. For this region, the rate is $0.045 per hour per AZ. With three AZs, the hourly charges will amount to $0.045 x 3 = $0.135 per hour. This charge reflects the Regional NAT Gateway being provisioned across three AZs."
So the hourly cost of a regional gateway across three zones matches three zonal gateways. It is not cheaper on the hourly meter. What it saves is the cross-AZ transfer you were paying to reach a single zonal gateway from two other zones, and what it saves operationally is the route table maintenance. AWS's worked example on the same page prices one gigabyte to the internet through a three-AZ regional gateway at $0.27 in total: "$0.135 hourly, $0.045 data processing, and $0.09 Data Transfer Out". Compare that against your own cross-AZ transfer bill rather than assuming the consolidation is free.
How do you find what yours is costing?
List every gateway, and the subnet, and therefore the zone, each one sits in:
aws ec2 describe-nat-gateways \
--filter Name=state,Values=available \
--query 'NatGateways[].[NatGatewayId,SubnetId,VpcId]' \
--output table
Then pull the spend, split by usage type, from Cost Explorer:
aws ce get-cost-and-usage \
--time-period Start=2026-07-01,End=2026-08-01 \
--granularity MONTHLY \
--metrics UnblendedCost \
--group-by Type=DIMENSION,Key=USAGE_TYPE \
--filter '{"Dimensions":{"Key":"SERVICE","Values":["Amazon Virtual Private Cloud"]}}'
Separate the hourly line from the per-GB line. If processing is large relative to hourly, you have a traffic problem. If regional data transfer is large relative to processing, you have a topology problem, and the fix is gateway placement rather than traffic reduction. That regional line is priced in what cross-AZ data transfer costs, and the gateway also holds a public address billed separately at $0.005 an hour.
Where the traffic turns out to be Amazon S3 or DynamoDB, the fix is neither: a gateway VPC endpoint carries that traffic off the NAT Gateway entirely and AWS does not charge for it. See when a gateway endpoint is free money for what it does and does not cover.
For traffic rather than cost, NAT Gateway publishes CloudWatch metrics at
one-minute granularity. The two worth watching are
BytesOutToDestination, "the number of bytes sent out through the
NAT gateway to the destination", and BytesOutToSource, "the
number of bytes sent through the NAT gateway to the clients in your VPC". The
NAT gateway metrics reference
lists all of them, and note the dimensions differ by mode: zonal gateways use
NatGatewayId alone, while regional gateways use it together with
AvailabilityZone.
Where does this show up in the CUR?
In the Cost and Usage Report these land in line_item_usage_type,
and you can attribute them per gateway through
line_item_resource_id. The
CUR 2.0 data dictionary
defines every column, which matters because usage-type strings are the only
reliable way to separate the hourly charge, the processing charge and the
transfer charge once they are all sitting under the same service name.