You have a 1 Gbps link and a 5 ms round trip to the server, yet the first chunk of a download crawls. The link isn’t the bottleneck and neither is the server. It’s TCP deliberately holding back, because a brand-new connection has no idea how much the network can take.

The Window You Don’t Configure

Throughput on a TCP connection isn’t governed by bandwidth directly — it’s governed by how many bytes you’re allowed to have in flight (sent but not yet acknowledged). That limit is the congestion window (cwnd), and the sender maintains it privately. It is not the receive window you see in packet captures; it’s the sender’s own guess about network capacity.

The achievable rate is simply:

text
   throughput ≈ cwnd / RTT

Double the window, double the rate. Double the round trip, halve it. This is why latency, not bandwidth, dominates short transfers.

The Exponential Ramp

A new connection starts with a small initial window — typically 10 segments (~14 KB). Every time a window’s worth of data is acknowledged, cwnd roughly doubles:

text
   RTT 1:  10 segments   (~14 KB)
   RTT 2:  20 segments
   RTT 3:  40 segments
   RTT 4:  80 segments
   ...

“Slow” start is a misnomer — the growth is exponential. But it starts small, so it takes several round trips to reach the link’s capacity. With a 100 ms RTT, climbing to a 1 MB window takes ~7 round trips, or most of a second, before you’re using the pipe.

Why It Hurts the Web

Most web objects are small enough to finish during slow start, before the window ever opens up. The connection never reaches steady state. So page load time is dominated by:

  • Round trips, not bandwidth — each one only lets the window double.
  • New connections, each of which restarts the ramp from the initial window.
text
   small file on a fast link:   [ slow start ] done
                                 └─ never reaches full rate

   large file on a fast link:   [ slow start ][ full rate .......... ]
                                              └─ ramp amortized away

What Actually Helps

  • Reuse connections. HTTP keep-alive and connection pooling keep cwnd warm so the next request skips the ramp. This is a big reason HTTP/2’s single multiplexed connection beats many short HTTP/1.1 ones.
  • Terminate TLS close to the user. A CDN edge cuts RTT, and since the ramp is measured in round trips, shorter RTT means a faster climb.
  • Don’t open six connections to dodge slow start — modern stacks share congestion state, and you mostly just multiply overhead.

Takeaways

  • Throughput is cwnd / RTT; a connection is only as fast as its window allows.
  • Slow start ramps the window exponentially but begins small, so short transfers finish before reaching full speed.
  • Web performance is round-trip-bound: reuse connections and cut RTT instead of chasing raw bandwidth.