TL;DR: Every S3 GET and DynamoDB call from a private subnet normally flows through your NAT Gateway at $0.045/GB. A Gateway Endpoint adds a route that sends that traffic over AWS's private backbone instead — for free, with no hourly charge, no code changes, and lower latency. Ten TB/month of S3 traffic through NAT is $450/month; through a Gateway Endpoint it's $0. Only two services qualify — S3 and DynamoDB — and that's exactly why this is the first networking fix to make.
The numbers
- Gateway Endpoint cost: $0. No hourly fee, no per-GB fee — unlike Interface Endpoints ($0.01/h + $0.01/GB).
- Worked examples from the source workflow: a 50 TB/month ETL pipeline was burning $2,250/month in NAT data processing → $0 (annualized: $27,000); VPC-attached Lambdas pulling 5 TB from S3 saved $225/month and got faster.
Do this
-
Create the endpoints (60 seconds each):
aws ec2 create-vpc-endpoint --vpc-id vpc-0abc123 \ --service-name com.amazonaws.us-east-1.s3 \ --vpc-endpoint-type Gateway \ --route-table-ids rtb-11111 rtb-22222Repeat with
...dynamodb. Both can coexist in the same VPC. -
Associate every route table that matters — this is the step everyone misses. Gateway Endpoints work via route-table entries, not VPC-wide magic. Twenty route tables means twenty associations (or the endpoint silently does nothing for the subnets you skipped).
-
Verify it's working: NAT Gateway CloudWatch bytes should drop visibly; VPC Flow Logs show traffic hitting the
pl-prefix list via the endpoint. -
Bake it into IaC so every new VPC ships with both endpoints from day one — set once, save forever.
Gotchas
- The route-table quirk is the #1 failure: endpoint created, nothing happens, hour of debugging — because it wasn't associated with the private subnets' route tables.
- IP-based bucket policies break. Policies allowing "our NAT's Elastic IP" stop matching when traffic arrives from the endpoint. Switch to the
aws:SourceVpcecondition (or IAM-based control). - Two services only. Secrets Manager, SQS, ECR, and friends need paid Interface Endpoints — different math, different cheat sheet.
- Not slower because it's free — you're removing a hop; latency typically improves. Traffic never touches the public internet, which auditors also like.
Skip this if
Almost never — if anything in a private subnet talks to S3 or DynamoDB, this is free money. The only genuine no-op: VPCs whose workloads never touch either service (then your lever is Interface Endpoints for the chatty paid services, or NAT consolidation for everything else).