Cloud Infrastructure · Cost Engineering

Egress Boundaries and Which Bytes Are Billed

Where traffic is metered in a cloud network, why the same byte can be free or charged twice depending on the path it takes, and how NAT and private endpoints move the boundary.

Data transfer appears on a cloud invoice as a set of line items distinguished by the pair of endpoints the traffic crossed between, not by the application that produced it. The same response body can generate no charge, one charge, or two, depending on which addresses the packets carried and which physical boundary they crossed on the way. Understanding the meter means understanding where the counters sit in the path, because a byte is billable at the point it is counted and not at the point it is written.

Meters sit at boundaries, and boundaries are topological

A cloud network is not a flat address space with a single border. It is a hierarchy: the instance, the subnet, the zone, the region, the provider’s backbone, and the public internet. Each boundary in that hierarchy has a meter attached to it, and each meter has its own price and its own direction convention. Traffic between two instances in the same zone crosses none of the metered boundaries above the host, so it is usually free. Traffic between two zones in the same region crosses the zone boundary and is charged in both directions at a regional inter-zone rate. Traffic between two regions crosses two regional boundaries and is charged at a higher inter-region rate. Traffic to the public internet crosses the provider’s border and is charged as outbound internet data transfer, which is the most expensive of the ordinary classes.

The direction convention is that outbound means leaving a boundary that the provider operates. Traffic entering from the internet is generally not charged for the bytes themselves, which is why a service that receives large uploads and returns small acknowledgements has a small data transfer line. The asymmetry is not a subsidy: inbound traffic terminates on capacity the provider already has, while outbound traffic must be carried across links the provider pays transit providers for.

The consequence is that placement determines price before any code runs. Two services in the same zone exchange bytes for free; the same two services split across zones pay an inter-zone rate; split across regions they pay inter-region rates plus, if a replica is involved, the cost of the replication itself. A chatty protocol that issues hundreds of small round trips per user action multiplies the inter-zone charge by the number of round trips, because each packet is counted rather than each byte of payload. Per-request charges on the same path compound this: the connection count and the byte count are separate meters.

The NAT gateway is a meter with a per-hour component

Private subnets have no route to the internet, so outbound traffic from them is forwarded through a network address translation device that the provider operates. That device has two charges: an hourly charge for its existence, independent of traffic, and a per-gigabyte charge for the data it processes. The hourly charge is the more frequently overlooked of the two, because it is incurred whether or not the gateway carries a byte. A gateway deployed per subnet per zone to preserve zone independence multiplies the hourly charge by the number of zones, and a deployment of three zones pays three times a fixed cost for capacity that is idle most of the time.

The per-gigabyte charge is not a transit charge. The traffic has already been metered once at the boundary it is leaving. The NAT charge is for the processing of translating addresses and ports, which means a workload that sends a large volume to the internet from a private subnet pays for the same bytes twice: once as NAT processing, and once as internet egress. This is visible in an invoice as two line items that both scale with the same quantity, and it is the reason a workload with heavy outbound volume is often cheaper to run in a public subnet with a route to an internet gateway, where the translation cost disappears and only egress remains.

The translation itself follows the standard behaviour in RFC 3022: the source address and source port are rewritten to an address the device owns, and the mapping is held in a table so that return traffic can be demultiplexed. Port exhaustion is a real constraint. Each translation consumes one port from the device’s pool, and a workload that opens many simultaneous long-lived connections to the same destination address and port can exhaust the available range. The symptom is failed connection attempts rather than a bill, but the fix is usually to add gateways, which multiplies the hourly charge.

Private endpoints move the boundary, and the price moves with it

A private endpoint attaches a provider service to a subnet so that traffic reaches it without leaving the provider’s network. The effect on the bill is a substitution rather than a reduction. Traffic that previously crossed the internet boundary and was charged as egress now crosses an endpoint boundary and is charged at the private endpoint’s per-gigabyte rate plus an hourly charge for the endpoint interface. Whether the substitution saves money depends on the relative prices and on the volume: the hourly component is fixed, so low-volume use is cheaper over the internet, and high-volume use is cheaper through the endpoint once the fixed component is amortized.

A second substitution appears in the same class of services: a gateway endpoint for object storage, which is attached to a route table rather than to an interface and is typically charged only for the data processed. Because the endpoint is a route rather than an interface, traffic to the service’s regional prefix is forwarded inside the provider’s network and no longer counted as internet egress. The saving is largest for workloads that read large objects from a private subnet, which is exactly the shape that also pays NAT charges for other traffic.

These substitutions all share a property that makes them hard to see in a forecast: they change which meter counts the byte, not how many bytes there are. A cost estimate built by multiplying an egress rate by a traffic volume will be wrong in both directions after a topology change, and the error is a fixed hourly amount plus a rate difference.

Counting is asymmetric and per-packet overhead is real

Two accounting details make measured volume differ from payload volume. The first is that meters count bytes on the wire, including transport and network headers. A TCP connection carries a minimum of 40 bytes of IPv4 and TCP headers per packet before any payload, so a protocol that sends many small messages pays a large ratio of header to payload. A one-byte message in a 41-byte packet is charged 41 times the payload size. Batching messages into larger writes reduces the counted volume without reducing the information transferred, and this is the one place where an application change directly moves a network line item.

The second detail is that retransmissions count. A packet retransmitted because of loss is counted twice, and a path with a high loss rate therefore bills more than the application’s logical traffic. Retransmission is also a latency cost, so the lossy path is worse on both axes, which makes the fix unambiguous.

Compression moves the same number in the other direction. Bytes are counted after compression at the transport layer if the connection negotiates it, so a compressible response costs less to deliver than its uncompressed size. The counter sits below the compression layer, which is why the saving is real and why it does not apply to encrypted payloads that are already compressed.

What a per-gigabyte model does not capture

A cost model that treats data transfer as a single rate per gigabyte misrepresents the structure of the meter. The rate depends on the boundary, and a single workload can cross three boundaries with three different rates. It also ignores the fixed components: NAT hourly charges, endpoint interface charges, and cross-zone connection charges that exist regardless of volume. And it ignores the per-request charges that accompany some paths, which scale with connection count rather than with bytes.

A defensible estimate enumerates the paths the workload actually uses, assigns each path its boundary-specific rate and its fixed components, and multiplies by the volume on that path. The result is a set of line items, not a single number, and it can be reconciled against the invoice at the level of each boundary. Where such an estimate diverges from the invoice, the divergence is usually a path that was not enumerated rather than a rate that was wrong. A workload that shares a NAT gateway or an endpoint across several services adds a further complication, since the fixed component must be divided by some key, and the choice of key is the allocation problem described in allocating shared cost to a unit of work.

The boundaries also interact with the commitment instruments described in commitment instruments and break-even utilization: data transfer is frequently excluded from the discounts that apply to compute, so a workload whose cost is dominated by egress does not benefit from a compute commitment in proportion to its spend. That asymmetry is worth knowing before a commitment is sized, since it changes the fraction of the bill that a discount can reach at all.

References

  1. RFC 1918: Address Allocation for Private Internets — IETF
  2. Amazon VPC User Guide — NAT gateways — Amazon Web Services
  3. RFC 3022: Traditional IP Network Address Translator (Traditional NAT) — IETF