Skip to main content
INS // Insights

VPC Endpoints vs. NAT Gateway: Cutting AWS Data Cost

Updated August 2026 · 4 min read

NAT Gateway is one of the more quietly expensive line items in a lot of AWS bills — not because the per-hour charge is high on its own, but because of the per-GB data processing charge that applies to every byte flowing through it. Traffic that's actually destined for other AWS services (S3, DynamoDB, Secrets Manager, and dozens of others) routinely gets routed through a NAT Gateway simply because that's the default path out of a private subnet, when a VPC endpoint could carry that same traffic privately, without touching the NAT Gateway at all.

Why This Traffic Shouldn't Be Going Through NAT in the First Place

NAT Gateway exists to let resources in a private subnet reach the public internet. But a large share of what looks like "internet-bound" traffic from a private subnet is actually AWS-service traffic — an application calling the S3 API, a Lambda function reading from Secrets Manager, an ECS task writing to CloudWatch Logs. None of that traffic needs to leave the AWS network at all, yet without a VPC endpoint in place, it's routed out through the NAT Gateway's public IP and back in, incurring NAT's per-GB data processing charge along the way.

Two Types of VPC Endpoints, Different Cost Profiles

Gateway endpoints (available for S3 and DynamoDB only) have no hourly charge and no per-GB data processing charge — they're added as a route table entry and the cost benefit is close to pure upside for any workload with meaningful S3 or DynamoDB traffic currently routed through NAT.

Interface endpoints (available for most other AWS services — Secrets Manager, KMS, CloudWatch Logs, ECR, SNS, SQS, and many more) do carry their own hourly charge per endpoint per Availability Zone, plus a per-GB data processing charge — but that charge is typically lower than NAT Gateway's, and for high-volume traffic to a specific service, the interface endpoint's flat AZ-based pricing usually undercuts routing the same volume through NAT.

# Terraform: S3 gateway endpoint (no hourly charge) + Secrets Manager interface endpoint
resource "aws_vpc_endpoint" "s3" {
  vpc_id       = aws_vpc.main.id
  service_name = "com.amazonaws.${var.region}.s3"
  route_table_ids = [aws_route_table.private.id]
}

resource "aws_vpc_endpoint" "secrets_manager" {
  vpc_id              = aws_vpc.main.id
  service_name        = "com.amazonaws.${var.region}.secretsmanager"
  vpc_endpoint_type    = "Interface"
  subnet_ids           = var.private_subnet_ids
  security_group_ids   = [aws_security_group.endpoints.id]
  private_dns_enabled  = true
}

Auditing Which Endpoints Are Worth Adding

The right approach isn't "add every possible VPC endpoint" — interface endpoints carry their own fixed cost, so they only pay off where traffic volume to that specific service is high enough to offset the hourly endpoint charge. The audit method: pull VPC Flow Logs or NAT Gateway CloudWatch metrics filtered by destination, identify which AWS service endpoints (by IP range or destination pattern) account for the largest share of NAT-routed traffic, and add interface endpoints for the highest-volume services first.

# Rough NAT traffic breakdown by destination service, from Flow Logs
aws logs start-query \
  --log-group-name /vpc/flow-logs \
  --start-time $(date -d '7 days ago' +%s) --end-time $(date +%s) \
  --query-string 'fields dstAddr, sum(bytes) as totalBytes | stats sum(totalBytes) by dstAddr | sort totalBytes desc | limit 20'

S3 and DynamoDB Gateway Endpoints Are Close to a Default Yes

Because gateway endpoints for S3 and DynamoDB carry no hourly or data processing charge of their own, the cost calculus almost always favors adding them if any meaningful S3/DynamoDB traffic currently transits NAT — there's very little downside case to make against adding these two specifically, which is why they're usually the first fix in any NAT cost review.

Multi-AZ Considerations

Interface endpoints are billed per Availability Zone they're deployed in, so a cost-conscious deployment matches endpoint AZ coverage to where the actual traffic-generating resources live, rather than deploying to every AZ in the VPC by default regardless of where compute actually runs.

This traffic-routing approach is part of our AWS cloud infrastructure capability, and pairs with the broader cost audit work covered in NAT Gateway cost reduction.

Talk to us about your AWS cost audit: 907-841-8407 or contact@rutagon.com.

Talk to us about your AWS cost audit →

Frequently Asked Questions

Do VPC endpoints eliminate NAT Gateway entirely?

Not necessarily — NAT Gateway is still needed for genuine internet-bound traffic (third-party APIs, package repositories); VPC endpoints only offload the specific AWS-service traffic that doesn't need to leave the AWS network.

How much can switching to VPC endpoints actually save?

It depends entirely on how much of your current NAT-routed traffic is AWS-service traffic versus genuine internet traffic — for workloads heavy on S3, DynamoDB, or other AWS API calls, the savings from gateway and interface endpoints can be substantial relative to NAT's per-GB charge.

Is there a downside to adding interface endpoints for every AWS service we use?

Yes — each interface endpoint carries its own hourly charge per AZ, so adding endpoints for low-traffic services can cost more than the NAT charges they'd save; prioritize by actual traffic volume from Flow Logs analysis.

Do VPC endpoints affect latency?

Interface endpoints typically reduce latency slightly compared to routing through NAT and back into AWS's network, since the traffic stays on the AWS private network path throughout.

Do gateway endpoints require any application code changes?

No — they work at the routing layer via route table entries, so applications continue calling the S3 or DynamoDB API exactly as before; the traffic path changes transparently.