NAT Gateway overuse

High NAT Gateway data-processing charges that could be reduced with VPC endpoints.

Last updated August 12, 2026

What triggers this finding

NAT Gateway charges of at least $50/month, or VPC/NAT spend representing at least 15% of your total AWS bill (from Cost Explorer).

Typical fix

Create free VPC gateway endpoints for S3 and DynamoDB so traffic to those services bypasses the NAT Gateway. Review which workloads still need NAT for internet access.

Example savings

Parsivex estimates roughly 30% of NAT Gateway data-processing charges are avoidable — often $15–$200+/month.

See also: Severity and savings estimates for how Parsivex calculates figures on your report.

A finding derived from the bill, not from a resource

Almost every other Parsivex finding starts from an inventory item and names it. This one does not. It is computed from Cost Explorer's NAT Gateway line for the most recent month, and its resourceIds list is deliberately empty, because the bill does not say which gateway in which VPC produced the charge.

That shapes how the finding should be read. It tells you the category is expensive; it cannot tell you which of your four gateways to look at, and it does not attempt to guess. Locating the traffic is the first piece of manual work the finding asks for.

A NAT Gateway bills on two independent meters: an hourly charge for the gateway's existence, and a data-processing charge for every gigabyte that passes through it in either direction. The second is what makes NAT expensive, and its defining property is that it stacks. Data processing is charged in addition to any data-transfer charge on the same bytes, so traffic to an AWS service that also carries a transfer cost is paying twice on one flow.

The two thresholds, and what trips them

Parsivex reports the finding when the latest month's NAT Gateway cost is at least $50, or when it accounts for at least 15% of that month's total spend. Either condition alone is enough. Severity is high above $200 a month.

The or is what produces the surprising cases. In a small account, the percentage rule fires on absolute amounts that are not worth anyone's afternoon — a $200 total bill with $32 of NAT crosses 15% and raises a finding worth roughly $10 in estimated savings. Conversely, in a large account, $50 of NAT is a rounding error on the total but still trips the absolute rule. Check which of the two conditions applies before deciding how much attention it deserves; the finding records the NAT cost and its percentage of total spend side by side for exactly that reason.

Because the detector reads only the most recent month, a one-off event — a bulk migration, a backfill, a data export — produces a finding that describes history rather than a standing cost, and it will disappear by itself on next month's scan.

The 30% is an assumption, not a measurement

The estimated saving is the NAT cost multiplied by a flat 0.30. Nothing in the scan measures where your traffic goes; the figure encodes a general observation that in a typical account, roughly a third of NAT-processed bytes are headed for S3 or DynamoDB, both of which are reachable through gateway VPC endpoints that AWS provides at no charge.

If your egress is genuinely third-party — external APIs, package registries, container images from outside AWS, webhook delivery — then the replaceable share is close to zero and the real saving is nothing like 30%. If your workload is a data pipeline moving terabytes to and from S3 through private subnets, the true figure can be well above it. Measure before committing to either:

aws ce get-cost-and-usage \
  --time-period Start=2026-07-01,End=2026-08-01 \
  --granularity MONTHLY --metrics UnblendedCost \
  --filter '{"Dimensions":{"Key":"USAGE_TYPE_GROUP","Values":["EC2: NAT Gateway - Data Processed"]}}' \
  --group-by Type=DIMENSION,Key=REGION

That separates the data-processing charge from the hourly charge and splits it by region. For the destination breakdown, VPC flow logs on the NAT gateway's subnet are the only reliable source — query them for destination addresses inside AWS service ranges, and the S3 and DynamoDB share becomes a number rather than an assumption.

When high NAT spend is the correct architecture

A large NAT bill is not automatically waste. Private subnets exist so that instances have no inbound route from the internet, and routing their egress through a managed gateway is the standard way to achieve that. The charge is the price of that posture.

The cases where the finding does not lead anywhere are common enough to name. Traffic to services with no gateway endpoint — most of AWS's service catalogue, and everything outside AWS — cannot be moved for free; an interface endpoint is available for many of them, but it carries its own hourly and per-GB charges and only pays off above a certain volume. Cross-region replication and third-party SaaS integrations are structurally NAT-bound. And a single gateway serving several busy subnets can look alarming on the bill while being the cheapest correct option available.

What changing the routing costs

Gateway endpoints for S3 and DynamoDB are free, and adding one is not a per-instance change — it inserts a prefix-list route into a route table, which redirects all traffic to that service from every subnet associated with that table. Two consequences follow, and both are quiet rather than loud.

An endpoint policy applies to everything that now routes through it. The default policy allows all access, but a restrictive one written for a subset of workloads will silently deny others once the route is in place, producing access-denied errors in applications that were never part of the change.

More subtly, the source identity that S3 sees changes. Requests that previously arrived from the NAT Gateway's public address now arrive through the endpoint, so bucket policies keyed on aws:SourceIp stop matching and must be rewritten against aws:SourceVpce or aws:SourceVpc. Nothing warns about this in advance; the first sign is a 403 from a bucket that worked yesterday.

Both changes are reversible — removing the route restores the previous path immediately — which makes a staged rollout, one route table at a time, the low-risk way to do it. Where the answer is an interface endpoint rather than a gateway endpoint, note that an unused one becomes an idle VPC endpoint finding of its own, so size the decision against actual traffic rather than adding endpoints defensively.