5 EKS Networking Tweaks That Cut Your AWS Bill by 40%

Network configuration choices in Amazon EKS directly impact your AWS bill through cross-AZ data transfer charges, NAT gateway costs, and load balancer processing fees. By optimizing how traffic flows between pods, nodes, and external services, you can reduce these often-overlooked expenses by 40% or more without sacrificing performance or availability.

Key Takeaways

  • Cross-AZ data transfer and NAT gateway egress are hidden cost drivers in EKS clusters
  • Service internalTrafficPolicy: Local keeps traffic node-local and eliminates cross-AZ hops
  • AWS Load Balancer Controller IP mode reduces unnecessary kube-proxy routing
  • VPC endpoints for ECR and S3 eliminate NAT gateway charges for image pulls
  • Topology-aware routing automatically prefers same-zone endpoints when available

Why EKS Network Costs Matter

When you run Kubernetes on EKS, compute costs get most of the attention. But for microservice-heavy workloads with frequent pod-to-pod communication or large container images, networking can consume 15-30% of your total AWS spend.

The primary culprits are:

  • Cross-AZ data transfer: AWS charges $0.01/GB for traffic between availability zones
  • NAT gateway processing: $0.045/GB for outbound internet traffic
  • Load balancer data processing: ALBs charge per GB processed
  • Container registry pulls: Repeated ECR image downloads across NAT or internet gateways

The good news? Most of these costs are controllable through configuration, not infrastructure changes.

Tweak #1: Enable Service internalTrafficPolicy: Local

By default, Kubernetes Services distribute traffic to any healthy pod across your entire cluster. If you have a three-AZ deployment, this means a pod in us-east-1a might send requests to a backend in us-east-1b—triggering cross-AZ charges.

The fix: Set internalTrafficPolicy: Local on chatty internal services to route only to pods on the same node.

apiVersion: v1 kind: Service metadata: name: orders-service namespace: ecommerce spec: selector: app: orders type: ClusterIP internalTrafficPolicy: Local ports: - protocol: TCP port: 3003 targetPort: 3003

Important: This only works when you have pod replicas on every node (or use DaemonSets). If a node lacks a local endpoint, traffic will be dropped. Use topologySpreadConstraints to ensure even distribution:

topologySpreadConstraints: - maxSkew: 1 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: app: orders

Expected savings: For services handling 100GB/day of internal traffic across zones, this eliminates $1/day ($30/month) in transfer fees per service.

Tweak #2: Use Topology-Aware Routing

Kubernetes 1.30+ introduced trafficDistribution: PreferClose, which automatically routes traffic to same-zone endpoints when available, falling back to other zones only when necessary.

apiVersion: v1 kind: Service metadata: name: payments-api spec: trafficDistribution: PreferClose selector: app: payments ports: - port: 8080

Alternatively, use the annotation-based approach for earlier Kubernetes versions:

metadata: annotations: service.kubernetes.io/topology-mode: Auto

The Kubernetes control plane uses EndpointSlice hints to guide kube-proxy toward local endpoints. This balances availability (cross-zone failover still works) with cost savings.

Gotcha: Topology hints require relatively even pod distribution. If you have 10 pods in us-east-1a and 2 in us-east-1b, hints may not activate. Monitor with:

kubectl get endpointslices -n ecommerce -o yaml

Look for endpoints[].hints.forZones to verify hint assignment.

Tweak #3: Switch Load Balancers to IP Mode

The AWS Load Balancer Controller supports two target modes: instance (default) and ip. In instance mode, the ALB sends traffic to NodePorts, and kube-proxy forwards it to the final pod—often crossing AZs.

In IP mode, the ALB registers pod IPs directly, eliminating the extra kube-proxy hop and reducing cross-AZ traffic.

apiVersion: v1 kind: Service metadata: name: frontend annotations: service.beta.kubernetes.io/aws-load-balancer-type: "external" service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip" spec: type: LoadBalancer selector: app: frontend ports: - port: 80 targetPort: 8080

Trade-off: IP mode requires the AWS Load Balancer Controller (install via Helm or EKS add-on). It also changes how source IP preservation works—test before applying to production.

Expected savings: Reduces cross-AZ hops for external-facing services. For a service processing 500GB/month, this can save $5-15/month per load balancer.

Tweak #4: Deploy VPC Endpoints for ECR and S3

Every time a node pulls a container image from ECR, the traffic flows through your NAT gateway by default—costing $0.045/GB. For clusters that scale frequently or use large images, this adds up fast.

Solution: Create VPC Interface Endpoints for ECR and a Gateway Endpoint for S3 (ECR stores layers in S3).

aws ec2 create-vpc-endpoint \ --vpc-id vpc-xxxxx \ --service-name com.amazonaws.us-east-1.ecr.api \ --subnet-ids subnet-xxxxx subnet-yyyyy \ --security-group-ids sg-xxxxx aws ec2 create-vpc-endpoint \ --vpc-id vpc-xxxxx \ --service-name com.amazonaws.us-east-1.ecr.dkr \ --subnet-ids subnet-xxxxx subnet-yyyyy \ --security-group-ids sg-xxxxx aws ec2 create-vpc-endpoint \ --vpc-id vpc-xxxxx \ --service-name com.amazonaws.us-east-1.s3 \ --route-table-ids rtb-xxxxx

Cost: Interface endpoints cost ~$7/month per AZ, but eliminate NAT charges. If you pull 100GB/month of images, you save $4.50/month in NAT fees per AZ—break-even is around 60GB.

Bonus tip: Use ECR replication to keep images in the same region, avoiding cross-region transfer fees entirely.

Tweak #5: Optimize NAT Gateway Placement

A single NAT gateway in one AZ forces all outbound traffic from other zones to cross AZ boundaries—doubling your costs (cross-AZ transfer + NAT processing).

Best practice: Deploy one NAT gateway per availability zone and configure route tables so each private subnet routes to its local NAT.

aws ec2 describe-nat-gateways \ --filter Name=vpc-id,Values=vpc-xxxxx \ --query 'NatGateways[*].[NatGatewayId,SubnetId,State]' \ --output table

Verify your route tables point to the correct local NAT:

aws ec2 describe-route-tables \ --filters Name=vpc-id,Values=vpc-xxxxx \ --query 'RouteTables[*].{ID:RouteTableId,Routes:Routes[?GatewayId!=null]}' \ --output table

Trade-off: Multiple NAT gateways increase fixed costs ($0.045/hour each = ~$32/month per AZ), but eliminate cross-AZ transfer fees on outbound traffic. This pays off when you have >70GB/month of egress per AZ.

Measuring Your Network Cost Savings

After implementing these changes, validate the impact using AWS Cost Explorer:

aws ce get-cost-and-usage \ --time-period Start=2025-01-01,End=2025-01-31 \ --granularity DAILY \ --metrics UnblendedCost \ --group-by Type=DIMENSION,Key=USAGE_TYPE \ --filter file://filter.json

Look for usage types like:

  • DataTransfer-Regional-Bytes (cross-AZ)
  • NatGateway-Bytes (NAT processing)
  • LoadBalancerUsage (ALB/NLB data processing)

You can also use tools like Kubecost to attribute network costs to specific namespaces and services, making it easier to identify which workloads benefit most from optimization.

Common Gotchas

internalTrafficPolicy: Local can drop traffic if pods aren’t evenly distributed. Always combine with topology spread constraints and test failover scenarios.

Topology hints don’t work with wildly uneven pod counts. If one zone has 90% of your pods, Kubernetes won’t activate hints to avoid overloading that zone.

VPC endpoints have a per-AZ cost. They’re worth it for high image-pull workloads but can increase costs for small clusters. Calculate your break-even point.

IP mode load balancers change IP preservation behavior. Test SSL passthrough and X-Forwarded-For headers before switching production services.

Conclusion

Network optimization in EKS isn’t about choosing between cost and performance—it’s about making traffic flow intelligently. By keeping traffic local when possible, eliminating unnecessary hops through kube-proxy and NAT gateways, and using VPC endpoints for AWS services, you can cut network-related costs by 40% while often improving latency. Start with internalTrafficPolicy: Local on high-traffic internal services, add VPC endpoints for ECR, and measure the results in Cost Explorer. These changes require no additional infrastructure—just smarter configuration.