Home › Decoder › Your AWS bill has two NAT Gateway lines. Here is how to read both.

Your AWS bill has two NAT Gateway lines. Here is how to read both.

A NAT gateway shows up on an AWS bill as two separate lines, and the second one is usually the surprise. This is how to read them, with the arithmetic, and how to find out what is behind the bytes before you change anything.

All prices below are US East (N. Virginia) list prices checked on 2026-11-04 against AWS's public price list and the VPC pricing page. Other regions differ. The numbers in the examples are made up to show the arithmetic; they are not from a real account.

The two lines

In Cost Explorer, group by Usage type and look for:

  • NatGateway-Hours: $0.045 per hour that a NAT gateway exists. Over a 730-hour month that is $32.85 per gateway, whether or not it carries traffic.
  • NatGateway-Bytes: $0.045 per GB processed by the gateway.

(Your usage types may carry a region prefix, such as USE1-NatGateway-Bytes.)

A made-up month

Say a small production VPC runs one NAT gateway per availability zone across 3 AZs, and the month looks like this:

NatGateway-Hours   3 gateways x 730 h x $0.045   =  $98.55
NatGateway-Bytes   4,200 GB x $0.045             = $189.00

The hourly line is a fixed cost of how many gateways you chose to run. The bytes line scales with traffic. In this example the bytes line is the larger one, which is common once a few services pull data through the gateway.

Now the useful question: where do those 4,200 GB go?

Check before you change anything

Do not touch a route table until you can answer these, because the fix depends on the answer:

  1. Which gateway carries the bytes? The CloudWatch metrics BytesOutToDestination and BytesOutToSource are published per NAT gateway. If one gateway carries nearly everything, that is where to look.
  2. Where are the bytes going? Turn on VPC Flow Logs for that gateway's network interface for a day (flow logs have their own cost, so keep the window short) and look at the top destinations. You are looking for S3 or DynamoDB address ranges, a container registry, a package mirror, or a SaaS vendor.
  3. Which private subnets use it? A fix only works for the route tables that you change.

The most common avoidable share: S3 and DynamoDB

If a big part of the traffic is from private subnets to S3 or DynamoDB, a gateway endpoint sends it over the AWS network instead of through the NAT gateway. AWS documents that there is no additional charge for gateway endpoints.

With the made-up numbers: if 60% of the 4,200 GB is to S3, that is 2,520 GB, and 2,520 x $0.045 = $113.40 a month that the endpoint removes. The other 1,680 GB still cost $75.60 until you find who sends it.

In the console: VPC > Endpoints > Create endpoint > AWS services > com.amazonaws.<region>.s3, type Gateway, pick the VPC and the route tables of the private subnets that reach S3. After creating it, check that each of those route tables shows a prefix-list route to the new vpce- target.

With the CLI:

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-EXAMPLE \
  --service-name com.amazonaws.us-east-1.s3 \
  --vpc-endpoint-type Gateway \
  --route-table-ids rtb-EXAMPLE1 rtb-EXAMPLE2

Two things to check first. Do it on one non-production route table before the rest. And look for any allow-list on the other side that assumes your traffic comes from the NAT gateway's Elastic IP: traffic through a gateway endpoint does not leave from that address. To roll back, delete the endpoint and traffic returns to the NAT route.

What else drives the bytes line

  • Container image pulls and package installs from private subnets, on every deploy and every autoscale event.
  • Logs, metrics and traces sent to an outside vendor from private subnets.
  • Services calling AWS APIs (ECR, STS, SQS, Secrets Manager) through their public endpoints. Interface endpoints can take that traffic, but they cost $0.01 per hour per AZ plus $0.01 per GB, so they only pay off when the bytes are large. Compare against $0.045 per GB first.

And watch the hours line too: a gateway that no private subnet routes to is pure fixed cost, and copying a three-AZ layout into every dev and staging VPC multiplies it.

The short version

  1. Cost Explorer, Usage type, daily view: find NatGateway-Bytes and NatGateway-Hours.
  2. Prove where the bytes go with per-gateway metrics and a day of flow logs.
  3. If it is S3 or DynamoDB, add a gateway endpoint to one route table, confirm, roll out.
  4. Watch the daily line for three days.

The price sources and the full step list for this line item are on one page: NatGateway-Bytes explained. It also has an upload box that reads your own Cost Explorer or CUR CSV in the browser and shows this line with the dollars for your account.

Find this line in your own bill

Drop in a Cost Explorer or CUR CSV. Billtrim reads it in your browser and shows the dollars and the steps for your numbers.

See a sample result

Paste your export: how to export a Cost Explorer CSV or CUR file in two minutes.