Map

Loading... [13 kB]

Wiki summarynetworkingtcpweb-performance โ†ณ show in map Markdown
title
Loading... [13 kB]
type
summary
summary
Why downloads stall at 13 kB: TCP slow start and the initial congestion window
tags
networking, tcp, web-performance
created
2026-04-06
updated
2026-07-22

A post by maurycyz about a mystery: every download in their gopher client stalled at exactly 13 kilobytes. The explanation is tcp-congestion-control, specifically the initial congestion window in TCP's slow start algorithm.

The problem

Packets travel independently across the internet and arrive out of order or not at all. TCP fixes this with sequence numbers (so packets can be reassembled) and acknowledgments (so lost packets get retransmitted). The article walks through both mechanisms with a "Hello, World!" example, showing how duplicate ACKs signal a gap and trigger retransmission.

Congestion control

Reliable delivery creates a nasty feedback loop: network overload causes dropped packets, which trigger retransmissions, which cause more overload. This actually broke the internet in 1986. TCP's answer is a congestion window โ€” a cap on how many packets can be in flight before hearing back from the receiver.

Slow start sets this window to 10 packets at connection open. Each ACK grows the window by one, so it doubles every round trip โ€” exponential growth. Once loss is detected, behavior depends on how the loss was noticed:

  • Duplicate ACKs (packets are still flowing, just one went missing): halve the window, switch to congestion avoidance (linear growth, +1 packet per RTT).
  • Timeout (silence โ€” packets may still be clogging the network): reset the window to 1 and restart slow start up to half the previous window.

The distinction matters because duplicate ACKs mean most data got through, while a timeout suggests the network might still be digesting what was sent.

The 13 kB number

Ten packets at ~1368 bytes each = 13.2 kB. That's everything a client receives in the first round trip. After two RTTs it's ~40 kB, after three ~92 kB. On high-latency links, the stall at 13 kB is perceptible.

Web performance implication

The first 13 kB of a page load should contain everything needed to paint the first screen โ€” critical CSS and JavaScript inlined. The commonly cited "14.2 kB budget" is in the right ballpark but not exact: packet sizes vary with hardware and path (MTU, VLANs), HTTP headers and TLS overhead eat into the budget, and HTTP compression works in your favor. The only way to measure your actual initial window is Wireshark, and even then it varies per visitor.

References

  • RFC 9293 โ€” TCP standard
  • RFC 5681 โ€” Congestion Control
  • RFC 6928 โ€” 10-packet initial window
  • high-performance-browser-networking โ€” Grigorik's book, free at hpbn.co, is the long-form version of this article: the same slow-start arithmetic plus TLS handshakes, HTTP/2 multiplexing, and mobile radio wake-up costs, all in page-load terms