Hidden Costs of AWS NAT Gateway. How to Identify Data Flow Cost Anomalies and Properly Use VPC Endpoints.

Devopsity 03 July 2026 13 min read
Contents

AWS NAT Gateway - Real costs, pitfalls, and optimisation strategies in VPC

AWS NAT Gateway is a managed service in Amazon VPC that allows instances in private subnets to reach the internet, but it's charged both for uptime (hourly) and for data processed (per GB), which can easily generate four-figure annual bills. Key savings come from reducing traffic through NAT Gateway (VPC Endpoints, caching, local repositories) and from a considered number of gateways per Availability Zone. In low-traffic environments, a NAT Instance may be an alternative, but in production NAT Gateway usually wins on reliability and scalability. Systematic FinOps (Cost Explorer, CloudWatch, budgets, automated cleanup of unused NATs) can reduce NAT Gateway costs by 30-50% without sacrificing security.

Why does AWS NAT Gateway generate high costs and when is it essential?

NAT Gateway is a critical component of AWS VPC architecture that allows instances in private subnets to access the internet without assigning them public IP addresses. From a security perspective, this is a standard pattern: application servers, databases, and backend microservices remain in private subnets while still being able to pull updates, container images, or communicate with external APIs.

Common use cases:

  • Pulling update packages from public repositories (e.g. yum, apt, pip)
  • Communicating with external APIs (payments, CRM, billing systems)
  • Sending logs and metrics to monitoring services outside the VPC
  • Downloading artefacts from Docker Hub, GitHub, public registries

You place NAT Gateway in public subnets and route traffic from private subnets through it via route tables. This is a correct security pattern, but if not designed consciously, it becomes one of the more “hidden” cost generators in AWS.

 

How does the AWS NAT Gateway cost model work and where do you actually pay?

AWS charges for NAT Gateway across two main dimensions that must be understood together: an hourly availability charge and a data processing charge.

Hourly availability charge

Hourly availability charge. Each NAT Gateway incurs a fixed cost for every hour it’s active. In us-east-1 this is approximately $0.045/hour (prices vary by region and should always be verified against the current AWS price list). A NAT Gateway running for a full month (720 hours) costs ~$32/month in availability charges alone.

In production environments where high availability is standard (at least 2 Availability Zones), this cost multiplies linearly with the number of gateways.

Data processing charge

Data processing charge (per GB). The second component is a charge for every GB of data processed through the NAT Gateway. In us-east-1 this is approximately $0.045/GB (also region-dependent).

Example: 1 TB (1024 GB) of data processed through NAT Gateway in a month: 1024 GB x $0.045/GB ≈ $46/month.

In practice, this data processing component is what can “spike” when:

  • Docker images are pulled repeatedly from public registries,
  • there’s no caching of dependencies (e.g. language packages),
  • traffic to AWS services (S3, DynamoDB, CloudWatch) goes through NAT instead of VPC Endpoints.

What you don’t pay for

What you don’t pay for:

  • Traffic between instances within the same VPC (local routing in route table)
  • Traffic to AWS services within the same VPC via VPC Endpoint (e.g. S3, DynamoDB)
  • Inbound traffic to instances (NAT Gateway only charges for outbound)

This means that correct use of VPC Endpoints and designing traffic flows within the VPC has a direct impact on your NAT Gateway bill.

 

NAT Gateway vs NAT Instance (EC2) cost and management comparison

AWS offers two main address translation mechanisms in VPC: the managed NAT Gateway and a NAT Instance based on EC2. The choice between them is a classic trade-off: cost vs reliability and operational simplicity.

FeatureNAT GatewayNAT Instance (EC2)
ManagementFully managed by AWSYou manage the EC2 instance
AvailabilityHigh, managed by AWSYour responsibility (HA, failover)
PerformanceUp to ~100 GbpsTypically up to ~10 Gbps (type-dependent)
Cost modelHourly + per-GB chargeEC2 instance cost + data transfer
ComplexityLow (few elements to maintain)Higher (patching, scaling, monitoring)

NAT Gateway is more expensive per GB but provides automatic scalability, no OS patching, and a simpler operational model. NAT Instance can make sense in test, dev, or very low-traffic environments.

 

Realistic cost calculation for a typical VPC architecture

Assume a typical production architecture:

  • 2 NAT Gateways (one per Availability Zone for high availability)
  • 500 GB of outbound traffic per month
  • Region: us-east-1

Calculation:

  • Availability: 2 NAT Gateways x 720 h/month x $0.045/h ≈ $64/month
  • Data processing: 500 GB x $0.045/GB ≈ $23/month
  • Total: ~$87/month for NAT Gateway

Over a year that’s more than $1,000 for the NAT layer alone. For organisations with high outbound traffic (many TB/month), costs can grow to several thousand dollars annually.

 

Key cost sources and savings potential

Cost areaCost mechanismTypical share of billSavings potential
Number of NAT Gateways (HA, multiple AZs)Hourly charge per NAT30-60%Up to 50%
Traffic to AWS services (S3, DynamoDB, CloudWatch)Data processing through NAT20-40%Up to 90% (VPC Endpoints)
Docker image and artefact downloadsLarge transfers from public registries10-30%20-60% (cache, ECR, S3)
Unexpected outbound traffic (scans, errors)Unplanned outbound connections5-20%50-100% (SG/NACL rules)
Unused NAT GatewaysHourly charge with no traffic5-15%100% (deletion)

 

Cost optimisation strategies for AWS NAT Gateway

1. Use VPC Endpoints instead of NAT Gateway for AWS services. Instead of routing traffic to AWS services (S3, DynamoDB, CloudWatch, Systems Manager) through NAT Gateway, use VPC Endpoints. For S3 and DynamoDB these are Gateway Endpoints, which are free (no hourly charge and no per-GB charge on the endpoint side).

Implementation:

1. Go to AWS Management Console > VPC > Endpoints.
2. Create a Gateway Endpoint for S3 and DynamoDB.
3. Select the VPC and route tables used by private subnets.
4. Save and verify that traffic to S3/DynamoDB no longer passes through NAT Gateway.

If a significant portion of outbound traffic goes to AWS services, deploying VPC Endpoints can reduce NAT Gateway costs by up to ~50%.

2. Consolidate traffic through a single NAT Gateway. If brief unavailability isn’t critical (e.g. dev, test, staging environments), consider using one NAT Gateway instead of one per Availability Zone. Savings: 50% of availability charges (~$32/month in our example).

3. Optimise image sizes and downloads. Many organisations generate unnecessary traffic through NAT Gateway:

  • Docker layer caching - use Amazon ECR as a private registry so images are pulled from within AWS, not from the internet
  • Local package repositories - host packages in S3 or internal repositories (e.g. Artifactory, Nexus)
  • CloudFront for static assets - serve static files via CloudFront instead of directly from EC2 behind NAT
  • Compression (gzip, brotli) - enable compression for all text-based transfers

Potential savings: 20-40% of outbound traffic.

4. Monitor spending and configure cost alerts. Use AWS Cost Explorer to track NAT Gateway spend. Set up budgets in AWS Budgets with notifications triggered when costs increase.

1. In AWS Billing Console open Cost Explorer.
2. Set filter Service = "NAT Gateway".
3. Analyse costs on a daily/monthly basis, looking for spikes.
4. In AWS Budgets create a Cost budget for NAT Gateway with an alert threshold (e.g. 80% of planned budget).

5. Consider a NAT Instance for low traffic. For non-production environments or very low traffic (<50 GB/month), a NAT Instance may be cheaper than NAT Gateway. Cost of t3.nano: ~$0.0052/hour = ~$3.74/month. Bear in mind you lose automatic availability and performance scaling.

 

How to reduce traffic through NAT Gateway in practice

Analyse actual traffic. Use VPC Flow Logs to see what’s actually passing through your NAT Gateway:

1. In AWS Console go to VPC > Your VPCs > Flow Logs.
2. Create a new Flow Log for a private subnet (or entire VPC).
3. Send logs to CloudWatch Logs (or S3) in a dedicated log group.
4. Analyse logs, identifying destination IPs/ports generating the most traffic.

Often it’s only through Flow Logs analysis that you discover unexpected downloads (e.g. CI/CD builds pulling gigabytes of artefacts) or misconfigured services generating excess traffic.

Cache dependencies. Use Amazon ECR instead of Docker Hub for container images. Host packages in S3 instead of pulling from public repositories. Cache API responses in ElastiCache (Redis/Memcached).

Restrict outbound traffic. By default many Security Groups have “allow all outbound” rules, which encourages uncontrolled traffic through NAT Gateway. Tighten these:

- Allow: Port 443 (HTTPS) to trusted public APIs (e.g. specific CIDRs or FQDNs via proxy)
- Allow: Port 53 (DNS) to Route 53 Resolver or dedicated DNS server
- Block: All other outbound connections (default deny)

This approach reduces attack surface, cuts unnecessary traffic, and makes auditing and FinOps easier.

 

AWS NAT Gateway alternatives

SolutionCostDrawbacksWhen to use
NAT Instance (EC2)EC2 instance + data transfer onlyNo automatic scaling, requires managementTest, dev, low-traffic environments
VPC Endpoint (Gateway)Free for S3 and DynamoDBLimited to selected AWS servicesS3, DynamoDB, Secrets Manager, Systems Manager
VPC Endpoint (Interface)~$0.01/hour + $0.01/GBMore expensive than Gateway EndpointPrivate subnet access to AWS services without NAT Gateway
Egress-only Internet Gateway (IPv6)FreeIPv6 onlyNew IPv6-native architectures

 

FinOps best practices for AWS NAT Gateway

Design your architecture with costs in mind. Before deployment, estimate expected outbound traffic (CI/CD, updates, APIs), calculate costs for different scenarios (1 vs 2 NAT Gateways, with VPC Endpoints vs without), and choose regions with lower pricing where possible.

Use Data Transfer Savings Plans. AWS offers Data Transfer Savings Plans that can reduce data transfer costs by up to ~40% if your outbound traffic is predictable and exceeds e.g. 1 TB/month.

Automate cleanup of unused NAT Gateways. NAT Gateways that are no longer routed to (no entries in route tables) still incur hourly charges. Implement a periodic cleanup mechanism:

import boto3


ec2 = boto3.client("ec2")


def find_unused_nat_gateways():
    nat_gateways = ec2.describe_nat_gateways()["NatGateways"]
    route_tables = ec2.describe_route_tables()["RouteTables"]

    used_nat_ids = set()
    for rt in route_tables:
        for route in rt.get("Routes", []):
            nat_id = route.get("NatGatewayId")
            if nat_id:
                used_nat_ids.add(nat_id)

    unused = [ng for ng in nat_gateways if ng["NatGatewayId"] not in used_nat_ids]
    return unused


if __name__ == "__main__":
    unused_nat = find_unused_nat_gateways()
    for ng in unused_nat:
        print(f"Unused NAT Gateway: {ng['NatGatewayId']} in state {ng['State']}")

Even simple automation, run monthly, can eliminate “forgotten” NAT Gateways and recover hundreds of dollars annually.

Document architectural decisions. Record why you chose 2 NAT Gateways instead of 1, or why you opted out of VPC Endpoints in specific cases. This makes cost reviews and cross-team discussions (FinOps, Architecture, Security) easier.

Review costs monthly. At the end of each month, analyse NAT Gateway costs in AWS Cost Explorer, compare with previous months, and identify anomalies.

 

Tools for monitoring NAT Gateway costs and traffic

AWS Cost Explorer - filter by “NAT Gateway” in the Service category, analyse costs daily and monthly, identify trends and anomalies. Free, built into the AWS Console.

CloudWatch Metrics - NAT Gateway publishes metrics to Amazon CloudWatch (bytes processed, active connections). Create dashboards to monitor traffic and set alarms when traffic increases by 50% or more vs average.

Example Terraform alarm:

resource "aws_cloudwatch_metric_alarm" "nat_gateway_traffic_spike" {
  alarm_name          = "nat-gateway-traffic-spike"
  comparison_operator = "GreaterThanThreshold"
  evaluation_periods  = 1
  metric_name         = "BytesOutToDestination"
  namespace           = "AWS/NATGateway"
  period              = 3600
  statistic           = "Sum"
  threshold           = 50000000000
  alarm_description   = "Alarm on sudden NAT Gateway traffic increase"
  actions_enabled     = true
  alarm_actions       = [aws_sns_topic.alerts.arn]

  dimensions = {
    NatGatewayId = "nat-xxxxxxxxxxxxxxxxx"
  }
}

Third-party tools - Cloudability, Anodot for automatic cost anomaly detection. Infracost for estimating infrastructure costs before deployment (Terraform).

 

FAQ - AWS NAT Gateway costs

Q: Is NAT Gateway free? A: No. NAT Gateway costs ~$0.045/hour + ~$0.045/GB of processed data. There is no free tier.

Q: Can I use NAT Gateway without incurring costs? A: Partially. Use VPC Endpoints instead of NAT Gateway for accessing AWS services (S3, DynamoDB, Secrets Manager). Those connections are free.

Q: How many NAT Gateways should I have? A: It depends on your availability requirements. For production: one NAT Gateway per Availability Zone (minimum 2). For dev/test: one is sufficient.

Q: Does traffic between EC2 and S3 always cost through NAT Gateway? A: Not if you use a VPC Endpoint for S3 (Gateway Endpoint). If traffic to S3 is routed through the internet (without an endpoint), every GB through NAT Gateway is charged.

Q: What’s the practical difference between NAT Gateway and NAT Instance? A: NAT Gateway is a fully managed AWS service - more expensive but provides high availability, scalability, and minimal operational overhead. NAT Instance is an EC2 instance you maintain yourself (patching, HA, monitoring), but may be cheaper at low traffic.

Q: Is the VPC Endpoint for S3 really completely free? A: Yes. Gateway Endpoints for S3 and DynamoDB have no hourly or per-GB charges on the endpoint side. However, you still pay standard S3/DynamoDB usage charges and any cross-region transfer.

Q: How can I realistically reduce NAT Gateway costs by about 50%? A: Apply three strategies: 1) Deploy VPC Endpoints for S3/DynamoDB and other AWS services, 2) Reduce the number of NAT Gateways where high availability isn’t critical (e.g. dev/test), 3) Cache downloads (Docker images, packages, artefacts) and minimise outbound traffic through architecture optimisation.

 

Summary

AWS NAT Gateway is an essential component of secure architectures, but it generates significant costs. Key takeaways:

  1. Two-dimensional billing: availability charge (hourly) + data processing (per GB)
  2. Costs add up quickly: 500 GB/month + 2 NAT Gateways = ~$87/month
  3. VPC Endpoints are a game-changer: they eliminate a large portion of traffic routed to S3 and DynamoDB
  4. Monitor actively: use Cost Explorer and CloudWatch Metrics
  5. Optimise your architecture: cache data, restrict traffic, consolidate NAT Gateways

Implementing these strategies can reduce NAT Gateway costs by 30-50% without sacrificing functionality. Over a year, that translates into meaningful savings for your AWS infrastructure budget.

Want to discuss AWS cost optimisation for your environment? The Devopsity team specialises in FinOps and infrastructure optimisation. Check out our FinOps (Cost Optimisation) service.

AWS NAT Gateway VPC cost optimisation FinOps

Read also:

Previous post Next post