← AWS

NAT Gateway data processing — the silent line item

07 May, 2026

NAT Gateway data processing is one of the most expensive and least-noticed items on a typical AWS bill. It hides inside the line that says "EC2 - Other," which is also where EBS, inter-AZ data transfer, and a few other charges live. So you can have a $200K-a-year NAT bill and never realize it because the line item doesn't say "NAT."

The pricing

NAT Gateway charges two things. An hourly fee per gateway (~$0.045/hour, so about $32/month per AZ). And a data processing fee of $0.045 per GB for everything that goes through it.

The data processing fee is what gets people. If your private-subnet workloads call AWS services, that traffic goes out through NAT, hits the public endpoint of the service, and comes back. You're paying NAT processing fees to talk to AWS itself.

A workload pulling 5 TB/month through NAT to call S3, DynamoDB, ECR, Bedrock, Secrets Manager, etc. is paying ~$225/month just on data processing fees. Multiply across services, regions, and growth and you're at $50K-$300K/year before anyone notices.

How to spot it

In Cost Explorer:

  1. Filter by service: EC2 - Other
  2. Group by Usage type
  3. Look for usage types containing NatGateway-Bytes

If NatGateway-Bytes is more than 30% of "EC2 - Other," you're in the territory where the fix below pays back.

The fix: VPC endpoints

VPC endpoints let private-subnet workloads talk to AWS services without leaving the VPC. Two types:

Gateway Endpoints are free. They exist for S3 and DynamoDB. If you're not using these, add them today. There's no downside.

resource "aws_vpc_endpoint" "s3" {
  vpc_id            = aws_vpc.main.id
  service_name      = "com.amazonaws.${var.region}.s3"
  vpc_endpoint_type = "Gateway"
  route_table_ids   = aws_route_table.private[*].id
}

Interface Endpoints (PrivateLink) cost about $0.01/hour per endpoint per AZ, plus $0.01/GB processed. They exist for most other AWS services (Bedrock, ECR, Secrets Manager, KMS, SQS, SNS, CloudWatch Logs, etc.). The math against NAT processing usually wins fast for any service called more than a few hundred GB/month.

resource "aws_vpc_endpoint" "bedrock_runtime" {
  vpc_id              = aws_vpc.main.id
  service_name        = "com.amazonaws.${var.region}.bedrock-runtime"
  vpc_endpoint_type   = "Interface"
  subnet_ids          = aws_subnet.private[*].id
  security_group_ids  = [aws_security_group.endpoints.id]
  private_dns_enabled = true
}

When NOT to use Interface Endpoints

If a service is called less than 50 GB/month from a given workload, the hourly endpoint fee can exceed what you'd pay in NAT processing. Run the math before adding every endpoint AWS supports.

Related

This is one of the seven levers in the post Seven AWS levers that cut $1.5M from a production SaaS bill, where it shows up as Lever 3.