Throughput

Performance

Throughput is the rate at which data actually crosses a link in a measured interval — the achieved rate, not the rated one. It sits at or below the link's bandwidth (capacity) and falls with packet loss, round-trip time, and undersized TCP windows.

9 min read Updated Aug 30, 2026

Full Explanation

Throughput is the rate at which data actually crosses a network path over a measured interval. It is the achieved rate, not the rated one. Throughput is not bandwidth. Bandwidth is the ceiling: "the maximum throughput/capacity over a communication link". Throughput is the share of that ceiling one real transfer obtains. Throughput is also not a fixed property of a link. The same link yields different numbers on different paths, at different hours, and to differently tuned hosts. That is because throughput is the outcome of one transfer over one path at one time. It moves with round-trip time, packet loss, window size, and protocol overhead. Cloudflare states the relationship plainly: "the portion of available bandwidth that a user actually achieves (throughput) is directly affected by loss and latency" (Measuring network quality). For a CDN, this has a practical consequence. Throughput is won mainly by shortening the path and keeping loss off it, not by provisioning a bigger pipe.

How it works

For content served over TCP, four limits act together. The lowest one decides the rate. None of this is CDN-specific. It is how TCP behaves on any path.

  • Loss. TCP reads a dropped packet as congestion and pulls back. After a retransmission timeout, the congestion window "MUST be set to no more than the loss window, LW, which equals 1 full-sized segment". After that, the sender "uses the slow start algorithm to increase the window" again (RFC 5681 section 3.1). The standard model of the resulting average rate is the TCP throughput equation in RFC 5348 section 3.1. In this model, the rate falls with round-trip time. It also falls with the square root of the loss event rate. RFC 5348 adds that retransmit timeout behaviour "dominates TCP throughput at higher loss rates". Loss therefore cuts throughput while the link's bandwidth stays completely unchanged.
  • Round-trip time. A sender can have only one window's worth of bytes outstanding. It takes a full round trip to send them and hear them acknowledged. For a fixed window, RFC 6349 section 3.3.1 gives the rate directly: TCP Throughput = TCP RWND × 8 / RTT. The RFC's own worked comparison on a T3 link (44.21 Mbps) shows the size of the effect. A 64 KB window delivers 42.8 Mbps at 10 ms RTT but only 20.5 Mbps at 25 ms. A 16 KB window gives 12.8 Mbps and 5.1 Mbps at those same two RTTs (Figure 3.3.1a). Distance costs throughput on a path that is neither congested nor lossy.
  • Window size. A sender may keep no more in flight than the smaller of its own congestion window and the window the receiver advertises. As the RFC states: "At any given time, a TCP MUST NOT send data with a sequence number higher than the sum of the highest acknowledged sequence number and the minimum of cwnd and rwnd" (RFC 5681 section 2). To fill a fast, long path, the sender must hold a bandwidth-delay product in flight: "BDP (bits) = RTT (sec) X BB (bps)". The minimum useful receive window is BDP / 8 in bytes (RFC 6349 section 3.3.1). Hence the buffer rule in RFC 6349 section 1: send and receive socket buffers "SHOULD be equal to or greater than BDP". Otherwise the transfer is capped below the link rate on an otherwise healthy network. Cloudflare's engineers report the same thing from the operator's side. They state: "It is this receive window that often limits throughput over high-latency networks" (Optimizing TCP for high WAN throughput).
  • Slow start. A fresh connection does not begin at the right window. It has to find it. RFC 5681 section 3.1 bounds the initial window at 2 to 4 segments, depending on segment size. That is 3 segments for a typical 1460-byte MSS. During slow start, the sender increases the congestion window "by at most SMSS bytes for each ACK received that cumulatively acknowledges new data". So the window roughly doubles each round trip. Growth of one segment per round trip is the later, slower congestion-avoidance phase, not slow start. RFC 6928 is an Experimental document. It raises the permitted upper bound to min(10*MSS, max(2*MSS, 14600)), but it makes the increase optional. So how much a connection may send in its first round trip depends on the sender's stack, not on the standard alone. Either way, several round trips pass before the window is large enough to use a fast link. That is why RFC 6349 section 2 states that its methodology "is not intended to predict the TCP Throughput during the transient stages of a TCP connection, such as during the Slow Start phase".

Why it matters for a CDN

Throughput is what a user experiences as speed. Cloudflare calls it "the metric every eyeball watches as they are downloading files". Download throughput is one of the metrics scored in its Aggregated Internet Measurement rubric. That rubric turns a speed test into per-scenario judgements for streaming, gaming and real-time chat, rather than a single number.

A CDN cannot change the subscriber's last mile. But it controls nearly everything above it. Serving from an edge server near the user reduces the RTT term in the formula above. That raises the achieved rate for the same window. The T3 figures above are the argument for edge placement in one table. A cache hit at the edge also removes the origin leg from the user's connection altogether. So loss on that leg can no longer shrink the congestion window the user is being served from. Throughput is also the budget an adaptive bitrate player spends. So throughput floors appear directly in CDN media products. Akamai's Quick Retry watches forward throughput while fetching an object. It reroutes the fetch when the throughput drops below a per-product target.

What CDNs do

  • Akamai. Enhanced Akamai Protocol "Increases the size of the congestion window" and "eliminates the slow-start algorithm that the TCP state variable uses for the congestion window". So an entire response can be sent at once. Akamai's docs say the behaviour is automatically included in a new property for all of the products it supports. They warn that removing it can significantly reduce performance. Quick Retry (the dynamicThroughtputOptimization behaviour in the API) detects slow forward throughput while an object is being fetched. It then attempts a different forward connection path. The trigger is per product, not universal. It is 5 Mbps for Adaptive Media Delivery and Download Delivery, and 2 Mbps for Object Delivery. The trigger is changeable only via an Akamai representative adding the override behaviour. Quick Retry is documented as incompatible with the Cache Tag behaviour in the same rule.
  • Cloudflare. Cloudflare's 2022 kernel work on this trade-off is published in detail. A 2015 fix for latency spikes had pinned tcp_rmem low. The post notes this "limits TCP throughput over high latency links". The fix was to raise the ceiling instead. Cloudflare set tcp_rmem max to 512 MiB with tcp_adv_win_scale of -2. That gives a maximum autotuned receive window of 128 MiB, sized for a 300 ms worst-case RTT. They also added an in-house sysctl, tcp_collapse_max_bytes, so the kernel drops a packet rather than spending milliseconds collapsing a full receive queue. Measured single-flow throughput to their Marseille data centre rose from 276 Mbps to 6600 Mbps from Iowa (121 ms RTT). It rose from 120 Mbps to 3800 Mbps from Melbourne (282 ms RTT). Even after the change, they report Melbourne is still "limited by the receive window on the Cloudflare host".

Watch out for

  • A single short transfer understates the path. The connection probably never leaves slow start. RFC 6349 section 2 excludes that transient from the measurement by design.
  • A well-behaved benchmark can hide a real problem. Cloudflare found that "iperf3 does not fill the receive queue". So it never exercised the buffer-limit path that was costing them throughput. They had to write a deliberately badly behaved reader to expose it.
  • The number is only as good as the window configuration at both ends. If either side's socket buffers are below the BDP, extra bandwidth recovers nothing (RFC 6349 section 1).
  • Windows above 64 KB need the window scale option, and "WSCALE can only be negotiated during the 3-way handshake". If either end omits it or picks too small a factor, "it cannot be renegotiated" for that connection (RFC 6349 section 5.2).
  • Do not measure over a broken network and call the result throughput. RFC 6349 section 3 offers "5% packet loss and/or 150 ms of jitter" as a guideline for conditions too poor for a meaningful TCP measurement.
  • Throughput is path- and time-specific. RFC 6349 recommends running longer than 30 seconds, each direction independently and then simultaneously, and at different times of day (section 5, section 3.3). A peak sample from one run is not a guaranteed rate.
  • One TCP flow is not the best a path can do. Where the BDP is far larger than host windows, "it is probably more realistic to test this network path with multiple connections" (RFC 6349 section 5.1). On high-BDP lossy paths, selective acknowledgment "SHOULD become part of the window size/throughput characterization" (RFC 6349 section 5).

Best practice

  • Measure the real path with a tool such as iperf3, or a timed curl download. Report a sustained rate over more than 30 seconds rather than a peak sample. Run each direction and repeat at different hours (RFC 6349 section 5).
  • Size send and receive socket buffers at both ends to at least the bandwidth-delay product. Confirm window scaling was actually negotiated before concluding the network is the bottleneck (RFC 6349 section 1).
  • Shorten the path before buying more capacity. For a fixed window, a lower RTT raises throughput directly. That is exactly what an edge close to users buys.
  • Keep loss off the delivery path. The modelled rate falls with the square root of the loss event rate (RFC 5348 section 3.1). So a loss rate small enough to look like noise can hold a transfer well below the link's bandwidth.
  • Publish a range or a distribution, not one bare figure. Quote the window sizes, RTT and duration alongside the rate. Otherwise the number cannot be reproduced.

Examples

# Measure throughput with curl
$ curl -o /dev/null -w 'Speed: %{speed_download} bytes/sec\n' https://cdn.example.com/bigfile.bin
Speed: 52428800 bytes/sec  # ~50 MB/s = ~400 Mbps

# iperf3: measure raw throughput
$ iperf3 -c cdn-edge.example.com
[ ID] Interval     Transfer    Bitrate
[  5] 0.00-10.00  1.09 GBytes 938 Mbits/sec

# Compare: bandwidth vs throughput
# Link bandwidth: 1 Gbps
# Measured throughput: 938 Mbps
# Overhead: ~6% (TCP/TLS/framing)

Frequently Asked Questions

Throughput is the rate at which data actually crosses a link in a measured interval — the achieved rate, not the rated one. It sits at or below the link's bandwidth (capacity) and falls with packet loss, round-trip time, and undersized TCP windows.

# Measure throughput with curl
$ curl -o /dev/null -w 'Speed: %{speed_download} bytes/sec\n' https://cdn.example.com/bigfile.bin
Speed: 52428800 bytes/sec  # ~50 MB/s = ~400 Mbps

# iperf3: measure raw throughput
$ iperf3 -c cdn-edge.example.com
[ ID] Interval     Transfer    Bitrate
[  5] 0.00-10.00  1.09 GBytes 938 Mbits/sec

# Compare: bandwidth vs throughput
# Link bandwidth: 1 Gbps
# Measured throughput: 938 Mbps
# Overhead: ~6% (TCP/TLS/framing)

Related CDN concepts include:

  • Bandwidth — Bandwidth is the maximum rate a network link can carry data, in bits per second …
  • Latency — Latency is the time data takes to travel from one point on a network to …
  • RTT (Round-Trip Time) (RTT) — RTT (round-trip time) is the delay from sending a packet until the response it triggers …
  • TCP (TCP) — TCP is the connection-oriented transport specified in RFC 9293: it delivers application data as one …