Kubernetes cross-zone traffic cost: the $0.02 per GB nobody attributes
Spreading pods across availability zones is good for resilience and expensive for chatty microservices. Every cross-zone hop is billed in both directions. Here is how much it adds and how topology aware routing removes most of it.
Quick answer
AWS charges $0.01 per GB in each direction for traffic between availability zones, so a cross-zone request path costs $0.02 per GB round trip. GCP charges $0.01 per GB between zones in a region, and Azure now charges for availability zone traffic too. Kubernetes spreads pods across zones by default and Services load balance uniformly, so roughly two thirds of internal traffic in a three-zone cluster crosses a zone boundary. On 50 TB per month of internal chatter that is about $667. Topology aware routing keeps traffic in-zone when endpoints allow, typically cutting the charge by 60 to 80 percent.
Kubernetes hides the network, which is mostly a virtue and occasionally a bill. A pod calls a Service by DNS name and gets connected to one of its endpoints. Nothing in that flow mentions that the chosen endpoint might be in a different availability zone, and that the cloud charges for the trip in both directions.
The rates
| Cloud | Cross-zone rate | Round trip per GB |
|---|---|---|
| AWS, between AZs in a region | $0.01 per GB each direction | $0.02 |
| GCP, between zones in a region | $0.01 per GB | $0.02 |
| Azure, between availability zones | $0.01 per GB | $0.02 |
| Same zone, private IP | $0 | $0 |
Two cents per GB sounds trivial. Microservice architectures move a lot of GB. A 30-service mesh where each user request fans out to 8 internal calls, each carrying 40 KB of request and response, generates roughly 320 KB of internal traffic per user request. At 50 million requests per month that is 16 TB, and if two thirds crosses zones, about $213. Multiply by chattier services, larger payloads, and replication traffic and mid-size clusters routinely hit $500 to $2,000 per month.
Why two thirds crosses a zone
In a three-zone cluster with endpoints evenly spread, a random endpoint selection puts the caller and callee in the same zone one time in three. The default kube-proxy behaviour is exactly that: uniform selection across all ready endpoints, with no zone preference. So 67 percent of internal service-to-service traffic is billable by default.
| Zones | Chance of same-zone hop | Billable share |
|---|---|---|
| 1 | 100 percent | 0 percent |
| 2 | 50 percent | 50 percent |
| 3 | 33 percent | 67 percent |
Topology aware routing
Kubernetes can prefer same-zone endpoints. Setting the service.kubernetes.io/topology-mode annotation to Auto, or using trafficDistribution set to PreferClose on newer versions, makes EndpointSlices hint that traffic should stay in-zone when there are enough endpoints in that zone to handle the load safely.
The safety valve matters: if a zone has too few endpoints, the hints are dropped and traffic spreads normally, which prevents a single-zone overload. In practice this means topology aware routing works well for services with at least 3 replicas per zone and does nothing for a 2-replica service across 3 zones.
| Configuration | Cross-zone share | Monthly cost on 50 TB |
|---|---|---|
| Default uniform routing | 67 percent | $667 |
| Topology aware, well-populated zones | 10 to 25 percent | $100 to $250 |
| Single-zone cluster | 0 percent | $0 |
The other cross-zone sources
Service-to-service calls are the obvious one. Several others are easy to miss. Load balancers with cross-zone balancing enabled forward to backends in other zones, and on AWS NLB that traffic is charged. Stateful replication, a three-node database or message broker spread across zones, replicates every write across zone boundaries continuously, which for a write-heavy workload can exceed all application traffic. Log and metric shipping to a collector that happens to live in one zone pulls from every node in every zone.
Service mesh sidecars add their own hop, and a mesh that load balances across zones without locality awareness doubles the problem. Most meshes support locality-weighted load balancing, which is the mesh equivalent of topology aware routing and should be enabled for the same reason. Seesidecar overhead for the compute side of the same decision.
Deciding how many zones
A single-zone cluster has zero cross-zone charges and no zone-failure resilience. That is the right trade for development, CI, and batch, and the wrong trade for production user-facing services. A reasonable policy is single-zone for non-production, three zones for production with topology aware routing enabled, and zone-pinned node pools for anything with heavy replication traffic that does not need zone-level resilience.
Moving all non-production clusters to a single zone is usually the easiest win: it removes the charge entirely and also speeds things up, at the cost of resilience nobody needed in staging.
Measuring it
Cross-zone charges show on the bill as a data transfer line, not as a Kubernetes line, which is why they are rarely attributed to the cluster at all. Tag the VPC and subnets, break the transfer meter down by zone pair, and compare it to the cluster's internal request volume. Node pool zone configuration is declared in Terraform, so price the topology against theresource catalog and the resilience-versus-transfer trade becomes an explicit number at design time rather than a mystery meter later.
FAQ
How much does cross-zone traffic cost in Kubernetes?
AWS charges $0.01 per GB in each direction between availability zones, so $0.02 per GB round trip. GCP charges $0.01 per GB between zones in a region and Azure charges for availability zone traffic as well. Same-zone traffic over private IPs is free. Mid-size clusters with chatty microservices routinely accumulate $500 to $2,000 per month in these charges.
Why does so much Kubernetes traffic cross zones?
Because default Service load balancing selects endpoints uniformly with no zone preference. In a three-zone cluster with endpoints evenly spread, a caller reaches a same-zone endpoint only one time in three, so 67 percent of internal service-to-service traffic crosses a zone boundary and is billable. In a two-zone cluster it is 50 percent.
What is topology aware routing and how much does it save?
It makes EndpointSlices hint that traffic should prefer same-zone endpoints, enabled through the topology-mode annotation set to Auto or trafficDistribution set to PreferClose. It typically drops the cross-zone share from 67 percent to 10 to 25 percent, taking a $667 monthly charge on 50 TB down to $100 to $250. It needs enough endpoints per zone, roughly three replicas per zone, or the hints are dropped for safety.
What else causes cross-zone charges in a Kubernetes cluster?
Load balancers with cross-zone balancing enabled forwarding to backends in other zones, stateful replication where a three-node database or broker replicates every write across zone boundaries, log and metric shipping from every node to a collector in one zone, and service mesh sidecars load balancing without locality awareness, which can double the service-to-service component.
Should development Kubernetes clusters use multiple zones?
Usually not. A single-zone cluster has zero cross-zone transfer charges and slightly lower latency, at the cost of zone-failure resilience that development, CI, and batch environments rarely need. Moving non-production clusters to a single zone removes the charge entirely and is typically the easiest available win on this line.
How does C3X help with Kubernetes cross-zone cost?
Node pool zone configuration and load balancer settings are declared in Terraform, so C3X prices the topology against a live catalog before merge. That makes the resilience-versus-transfer tradeoff an explicit number at design time, rather than an unattributed data transfer meter on the invoice that nobody connects back to the cluster.
What to do next
Make zone topology a priced decision. C3X reads your Terraform and prices your resources against a live catalog. Start with the quickstart.
Share this post
Try C3X on your own Terraform
Free and open source. No API key required. One command to install, one command to estimate.