Nothing about a cloud bill reads less like engineering and more like a tariff table than data transfer. Compute is priced per hour and storage per gigabyte-month, and both track something a team decided to provision. Egress tracks something nobody decided at all: the boundaries a byte happened to cross on its way from one process to another. Two systems that do identical work, built by teams of identical skill, can differ by an order of magnitude on this line purely because one spread its replicas across zones for availability and the other did not. This article is about the structure of that pricing rather than its current numbers — which boundary is free, which is charged, which is charged twice, what stacks on top of the per-gigabyte rate, and which levers actually move the total. Every rate below is explicitly assumed for arithmetic; read your own provider's current table before committing to a design.

The boundaries the bill actually charges for

Data transfer pricing has one organising idea: the rate is a property of the boundary crossed, not of the service that sent the bytes. Inbound traffic from the internet is generally free everywhere, which is the asymmetry that makes the whole thing a ratchet. Outbound is priced by how far the packet went. Traffic that stays inside one availability zone, between resources addressed by their private addresses, is normally free. Traffic between zones in the same region is charged, and on at least one major provider it is charged on both the send and the receive side. Traffic between regions is charged as egress from the source region, at a rate that depends on which region it left. Traffic to the internet is charged at the highest per-gigabyte rate and is tiered, so the marginal gigabyte gets cheaper as monthly volume grows, usually after a small monthly allowance.

The fifth box in the figure below is where the stub this article replaces got it wrong, and the error is worth naming because it is a common one. A destination in another cloud provider is not a billing category. Unless a dedicated circuit is in the path, that traffic leaves through the internet gateway and is billed as ordinary internet egress at the ordinary internet rate. The destination being someone else's data centre does not make it more expensive; what makes multi-cloud transfer expensive is that it is continuous and it scales with change rate, which is a topology problem rather than a pricing one.

Cloud egress cost — data transfer + VPC endpoint + CDNwhich boundary the bytes crossedCross-AZoften charged both waysCross-regionrate set by source regionTo internettiered by monthly volumeTo another cloudstill internet egressPrivate endpointskeep bytes off the edgeCDN offloadfewer origin fetchesPayload sizecompress + batchDedicated circuitport fee + lower rateAttributionflow logs joined to ownersMetricsGB per team, GB per requestOps — cost alerts + FinOps + design reviewroutecachecompresslinktagwatchwatchoperateoperate
The boundary a byte crosses sets its rate; the row below is the set of levers that change either the rate or the number of bytes.

Everything below the top strip is a lever. Some change the rate the bytes are charged at, some change how many bytes there are, and one changes only who gets billed. Confusing the three is the usual reason an optimisation project produces no visible saving.

Advertisement

Cross-AZ is the charge that surprises people

Internet egress does not surprise anyone. It appears on a bill under an obvious name, it correlates with traffic the business can see, and someone in finance has asked about it before. Cross-zone transfer is different, and it is the line that produces the meeting. It is invisible in the architecture diagram, because the diagram shows services calling services and says nothing about which zone each replica landed in. It is invisible in the code. And it is generated by exactly the thing the reliability review asked for: spreading every tier across zones so that losing one zone loses a fraction of capacity rather than all of it.

The arithmetic is unforgiving because of the both-directions rule. Take a service mesh where a request fans out to four downstream calls, each carrying a 20 KB request and returning an 80 KB response, and assume three zones with no zone affinity in the load balancing — so roughly two thirds of every hop crosses a zone boundary. At 10,000 requests per second that is 4 GB/s of application payload, of which about 2.7 GB/s crosses a boundary, or roughly 7 PB in a month. At an assumed $0.01 per GB charged on each side, that is about $0.02 per crossed gigabyte and a monthly line near $140,000 — for traffic that never left the region and never touched a router the team owns.

The number is deliberately large to make the point that this is a topology cost, not a traffic cost. The same workload with zone-aware routing, where a caller prefers the replica in its own zone and falls back across zones only when the local one is unhealthy, pays a small fraction of it while keeping the same failure tolerance. The general shapes that generate this traffic are catalogued in cloud FinOps; what follows here is the arithmetic and the fixes.

The charges that stack on top of the per-GB rate

The per-gigabyte transfer rate is rarely the whole charge, and the additions are the reason a bill can exceed a careful estimate by a factor of two. Most of them are processing charges: a managed component in the path bills for every gigabyte it handles, in addition to whatever the transfer itself costs and in addition to its own hourly fee. A managed NAT gateway charges per hour and per gigabyte processed, and it processes everything routed through it — including traffic to a managed service in the same region, which is not internet egress at all and would have been free had it taken a private path. That is the charge worth hunting first: processing fees on bytes that never needed to leave the network. When the destination genuinely is on the internet, the processing fee stacks on top of the egress rate rather than replacing it.

Load balancers add a similar layer, and the details vary by product and change often, so the durable rule is the shape rather than the specifics: some balancer types bill cross-zone traffic as data transfer while others fold it into their own processed-bytes charge, and you have to check per type. A transit hub bills per attachment per hour and per gigabyte processed, so a hub-and-spoke design converts traffic that was free inside a VPC into metered traffic the moment it crosses the hub — a real trade against the mesh arithmetic covered in VPC peering. Interface endpoints bill per hour per zone and per gigabyte processed. Cross-region replication of an object store or a database bills the transfer plus the request charges on the writes it performs at the far end.

Practically, this means the useful mental model is not a rate but a path. Enumerate every managed box a byte passes through, add each one's processing charge to the boundary rate, and only then compare designs. The path itself — which gateway, which route table entry, which endpoint — belongs to cloud networking and the NAT gateway article; the point here is that each of those boxes is also a meter.

Private paths, and when an endpoint costs more than it saves

Private service endpoints exist to keep traffic to a managed service inside the provider's network, and they come in two economic shapes that are easy to conflate. The route-table variety — the kind that adds a prefix for an object store or a key-value service to a route table — typically carries no hourly and no per-gigabyte fee. For those services, adding one is close to unconditionally correct: it removes NAT processing charges and internet egress on traffic that was always staying in-region. There is no breakeven to compute; there is only the question of why it is not already there.

The interface variety, which places a network interface in your subnets and resolves the service name to a private address, is billed per interface-hour in each zone plus a per-gigabyte processing charge. That combination has a genuine breakeven. Assume $0.01 per interface-hour, three zones for availability, and 730 hours in a month: the fixed cost is about $22 per month per service before a single byte moves. Assume it saves $0.045 per GB of NAT processing and costs $0.01 per GB to process, a net saving of $0.035 per GB. The endpoint pays for itself at roughly 630 GB per month for that one service. Below that volume — a low-traffic control-plane API called a few thousand times a day — the endpoint is a cost increase, and a fleet of forty such endpoints deployed reflexively across every account is a four-figure monthly line bought for nothing.

The correct conclusion is not that endpoints are expensive; for the high-volume services they are the single largest lever available. It is that the decision is per service and volume-dependent, and that the same architecture review should be asked to justify each one. How the endpoint is exposed, resolved and secured is private connectivity; the number above is the only part that belongs here.

CDN offload changes the rate and the volume

Putting a CDN in front of an origin does two economically distinct things, and teams that model only one of them are usually disappointed. The first is volume: every request served from an edge cache is a request the origin does not answer, so origin egress falls in proportion to the cache hit ratio. The second is rate: the leg from origin to edge and the leg from edge to client are billed separately, at different rates, and on some providers the origin-to-edge leg is zero when the origin is inside the same provider. Those two effects multiply, which is why the saving can be much larger than the hit ratio alone suggests — and why a low hit ratio can leave the whole exercise roughly cost-neutral.

Worked, with assumed rates: 500 TB per month of static assets served directly from an origin at an assumed $0.08 per GB is about $40,000. Move it behind a CDN with a 90% hit ratio, an assumed $0.06 per GB edge rate and a free origin-to-edge leg, and the client-side bill is about $30,000 with the 50 TB of origin fetches costing nothing — around a 25% saving. Now improve the hit ratio to 98% by fixing cache keys and it barely moves, because at a free origin leg the hit ratio was never the dominant term; the rate difference was. Reverse the assumption so the origin leg is charged, and the hit ratio becomes the dominant term instead. Which term dominates depends on whether the origin leg is free, so establish that first.

Two second-order effects deserve a line each. Per-request fees mean a workload of very small objects can pay more in requests than it saves in transfer. And a shield or mid-tier cache in front of the origin collapses the fan-out of many edge locations independently missing on the same object, which matters most for long-tail content. The caching mechanics themselves are covered in CDN architecture and content delivery networks; the economics are what this section owns.

Making the payload smaller before making the path cheaper

Every lever so far changes the rate. The other half of the problem is the byte count, and it is usually the cheaper half to fix because it needs no new infrastructure. Compression is the obvious one and is still routinely missing on internal service-to-service traffic, where nobody thought of it as a network path at all: verbose JSON over an internal API compresses by a large factor, and the CPU cost of that compression is charged at compute rates that are, per byte, far below transfer rates. A binary encoding does the same job structurally rather than statistically, and does it on both the wire and the parser.

Chattiness is the subtler one. A per-item API that returns a fixed envelope with each item pays the envelope tax once per item, and batching collapses it. Polling loops that re-fetch an unchanged resource pay full price for a negative answer, where conditional requests and a validator pay almost nothing. An analytics job that reads a whole columnar dataset because the query engine could not push a predicate down transfers hundreds of times what the answer needed — and this is where a compact file format and correct partitioning earn their keep, because a projection and partition pruning are transfer optimisations as much as they are query optimisations.

Two hidden generators are worth calling out by name. Telemetry: shipping every log line and every raw metric sample to a third-party observability platform is internet egress at full rate, continuously, and it is almost never modelled as such — sampling, aggregation at the edge and dropping debug-level records at source are transfer optimisations disguised as logging policy. And backup: an unthrottled nightly full copy to an off-provider target moves the entire dataset every night, where an incremental with a change-block list moves the delta. Neither shows up in a traffic dashboard built around user requests.

Advertisement

Placement, zone-aware routing and where the replicas sit

The most effective egress work is not an optimisation at all; it is deciding where things sit. Colocation is the whole trick: put the compute in the same zone as the data it reads, and the traffic between them is free. That is why a batch job placed by a scheduler with no topology awareness can cost more than the same job pinned to the zone holding its input, and why a read replica promoted in another zone quietly changes a monthly bill.

Several systems now expose this explicitly, and using those features is the highest-leverage change available. Kafka supports fetching from the nearest replica rather than always from the partition leader, so a consumer can read from a follower in its own zone — a change that removes the majority of cross-zone traffic from a large consumer fleet without weakening durability. Kubernetes exposes topology-aware routing so that a service's endpoints are preferentially local to the caller, with automatic fallback when local endpoints are unhealthy. Service meshes express the same idea as locality-weighted load balancing with failover priorities. The shared pattern: prefer local, fail over globally, which preserves the availability property the multi-zone spread was bought for while declining to pay for it on every healthy request.

The honest caveat is that zone affinity trades against load distribution. If zone A holds 60% of the callers and 33% of the replicas, strict locality overloads them, so these mechanisms all include a threshold at which they spill over. Tune that threshold with the reliability team present, because a purely cost-driven setting produces a hot zone and the incident that follows costs more than the transfer did. The same tension applies to placing an entire tier in one zone to eliminate the charge outright — legitimate for a stateless, quickly rebuildable batch tier, indefensible for anything on the critical serving path.

Dedicated interconnect economics

A dedicated circuit between a data centre or colocation cage and the cloud replaces a variable cost with a fixed one plus a lower variable one. The bill has three parts: a port-hour charge for the circuit capacity, sometimes a separate charge from the carrier or exchange providing the physical cross-connect, and a per-gigabyte transfer-out rate that is substantially below the internet rate. Nothing about it is subtle, but it is frequently mis-modelled because teams compare only the per-gigabyte rates and forget that the port is charged whether or not a byte moves.

The breakeven is a one-line calculation. Assume a port costing $0.30 per hour, about $220 per month, plus $100 per month for the cross-connect; and assume internet egress at $0.08 per GB against a circuit rate of $0.02 per GB, a saving of $0.06 per GB. The circuit pays for itself at roughly 5.3 TB per month, which for any workload replicating data to on-premises or serving a private enterprise integration is a low bar. Above that, the saving grows linearly while the fixed cost does not, and it converges on a 75% reduction under these assumptions.

Two adjustments keep this honest. A single circuit is a single point of failure, and the redundant configuration a production design actually needs — two circuits, ideally at two separate locations — doubles the fixed cost and moves the breakeven with it. And capacity is committed in fixed steps, so a workload that outgrows a port faces a discrete upgrade rather than a smooth increase; sizing for the peak means paying for the peak all month. For traffic between two clouds specifically, an exchange provider terminating circuits from both sides is the same trade with the same arithmetic, and it is the only way that traffic stops being internet egress.

The bill aggregates, the flow logs disaggregate

The hardest part of egress work is usually not knowing what to fix but knowing who is generating it. Billing data reports transfer under coarse usage types — an internal identifier meaning roughly regional transfer, or transfer out to the internet, scoped to an account and a region and sometimes a resource. That is enough to know a region moved a petabyte and not remotely enough to know which two services were talking. Cost allocation tags, the primary tool everywhere else in FinOps, are weak here for a structural reason: a transfer charge belongs to a pair of endpoints, and a tag belongs to one resource. Whose tag should the charge carry — the sender's, or the receiver who asked?

The mechanism that answers the question is network flow logging. Flow records carry source address, destination address, byte counts, the interface, and on most providers the zone or subnet, which is exactly the pair the bill lacks. The work is a join: build an inventory mapping every private address and interface to an owning service and team, join the flow records against it, aggregate bytes by ordered pair, and classify each pair by boundary using the subnet-to-zone and CIDR-to-region maps. What comes out is a ranked list of service-pair conversations by billable gigabyte, which is the artefact that makes the problem actionable — typically three or four pairs account for most of the spend, and each has an obvious fix from the sections above.

Two practical warnings. Flow logs are themselves charged for ingestion and storage, and on a busy network at full fidelity they can become a noticeable line of their own; sample, or enable them on the subnets under investigation rather than everywhere permanently. And what to do with the resulting allocation — showback, chargeback, budgets, anomaly alerting — is the operating loop owned by cloud FinOps, not this article. Feed it the pairs; let it own the policy.

Data gravity, and what an exit waiver does not cover

Egress pricing has a strategic consequence that outlives any particular rate card: because inbound is free and outbound is not, every dataset becomes progressively more expensive to move the longer it sits. The multi-cloud strategy article develops the resulting dynamic in full, and the migration mechanics are in cloud migration patterns. One point belongs here because it is specifically a pricing fact and it is widely misread.

Major providers now waive data transfer charges for customers leaving the platform entirely, under pressure from regulators who identified switching costs as a competition problem. This is real and it is worth knowing. It is also narrower than the headline suggests, in ways that matter for design. The waiver is conditional on exit: it applies to moving data out as part of terminating the relationship, generally requires a request and a verification step, and typically comes with a window and an expectation that the accounts close. It does not apply to a steady-state architecture — a cross-provider replication stream, an analytics engine in one cloud reading a bucket in another, a disaster-recovery copy kept warm elsewhere. Those are ongoing operations, not an exit, and they pay the ordinary rate forever.

So the waiver removes a one-time barrier to switching; it does not make continuous multi-provider data flows cheap, and a design that quietly assumes it does will be wrong by the recurring cost of the stream. The durable planning number for anything continuous remains the standard internet rate multiplied by the change rate of the dataset, not by its size.

Failure modes worth designing against

A short catalogue, each one seen repeatedly. The NAT double charge: private compute reaching an in-region managed service through a NAT gateway, paying processing and internet egress on traffic that a route-table endpoint would have carried free. It is the highest-return five-minute fix in this article. The zone-oblivious mesh: every tier spread across zones with no locality preference, so most internal hops cross a boundary and get billed on both sides. The chatty replica: a database read replica or search index in another region kept current by a continuous stream whose cost scales with write rate, sized by someone who reasoned about dataset size instead.

The observability pipe: full-fidelity telemetry shipped off-provider at internet rates, growing linearly with fleet size and invisible in every traffic dashboard because it is not user traffic. The cold-tier read: an archive tier chosen for its storage rate and then read monthly, paying retrieval and transfer that dwarf the saving. The failover surprise: a design that shifts traffic across a region or provider boundary during an incident, generating its largest transfer bill on the day nobody is watching the budget — model that cost in the disaster-recovery plan, because discovering it after the incident is how a good failover decision becomes a bad meeting.

The organisational fix is smaller than it sounds: put one question into the design review. Which boundary does this traffic cross, how many gigabytes per month, and through which metered boxes? A design that cannot answer it has not been costed, and a team that can answer it in the review will not need the meeting later. Pair that with a single per-team gigabyte metric derived from the flow-log join, and egress stops being a line that surprises anyone.

Egress is priced by the boundary a byte crosses, not by the service that sent it — free inside a zone, charged between zones and often in both directions, charged between regions, charged most to the internet, and a destination in another cloud is just internet egress rather than a category of its own. Add the processing charges of every metered box in the path before comparing designs. The large levers are placement and zone-aware routing, route-table endpoints for in-region services, CDN offload where the origin leg is free, and smaller payloads; the enabling step is joining flow logs to an ownership inventory, because the bill records the total and never the pair.