HomeNetworks & Graph TheoryTCP Congestion Control

🌐 TCP Congestion Control

Watch a TCP congestion window grow through slow start and congestion avoidance, then collapse on packet loss. Compare Tahoe, Reno and CUBIC-style backoff with a live cwnd sawtooth, link pipe and bottleneck buffer.

Networks & Graph Theory3DAdvanced60 FPS
tcp-congestion ↗ Open standalone

About this simulation

This simulator runs a real TCP congestion-control loop RTT by RTT: cwnd doubles every round trip during slow start, switches to linear additive increase in congestion avoidance once it passes ssthresh, and gets cut back — multiplicatively — the moment the bottleneck buffer overflows or a random loss hits. Switch between Tahoe, Reno, NewReno and a CUBIC-ish variant to see how each backs off differently, and tune bandwidth, RTT, buffer size and loss rate to reproduce lossy wireless links, tiny router buffers, or high bandwidth-delay-product paths.

🔬 What it shows

The classic cwnd sawtooth: a cyan exponential ramp during slow start, a purple linear climb during avoidance, and a red drop on loss when the bottleneck buffer (shown filling in the pipe diagram) overflows or a random packet is dropped.

🎮 How to use

Adjust bottleneck bandwidth, RTT, buffer size and random loss rate, pick an algorithm variant (Reno, Tahoe, CUBIC-ish, NewReno), or load a preset (Ideal link, Lossy wireless, Small buffer, High BDP) and watch phase, cwnd, ssthresh, throughput and drops update live.

💡 Did you know?

Tahoe resets cwnd all the way back to 1 packet on any loss and restarts slow start from scratch, while Reno and NewReno only halve cwnd and jump straight back into congestion avoidance — one reason Reno-family TCPs recover throughput so much faster after a single lost packet.

Frequently asked questions

What is the congestion window (cwnd)?

It's the number of packets a TCP sender is allowed to have in flight without an acknowledgement. It starts at 1 packet and grows according to the current phase — slow start or congestion avoidance — until loss forces it back down.

What triggers the sawtooth pattern?

cwnd keeps growing (exponentially in slow start, then linearly in avoidance) until it exceeds what the bottleneck link and buffer can absorb. A packet is dropped, cwnd is cut multiplicatively, and the climb starts again — repeating this cycle draws the familiar sawtooth.

What is ssthresh?

It's the slow-start threshold: the cwnd value at which the sender switches from doubling every RTT to adding roughly one packet per RTT. It's set to half of cwnd right after a loss, which is why it steps down on every sawtooth drop.

How does CUBIC differ from Reno?

Reno increases cwnd linearly regardless of how long ago the last loss was. CUBIC-ish growth here follows a cubic function of time since the last loss, growing slowly right after backing off, then accelerating back toward the previous window size — useful on high-bandwidth-delay-product paths where linear growth alone recovers throughput too slowly.

Why does a small buffer cause more frequent drops?

A small bottleneck buffer fills up as soon as cwnd slightly exceeds the link's bandwidth, so it overflows sooner and more often than a large buffer would — try the "Small buffer" preset and compare the sawtooth's frequency to "Ideal link".

⚙ Under the hood

TCP's congestion window: slow-start doubling, AIMD increase, multiplicative decrease on loss (Tahoe/Reno/CUBIC). Watch cwnd sawtooth and buffer overflow.

NetworksTCPCongestion ControlAIMDSlow Start

3D · Three.js / WebGL renderer · 60 FPS target · runs fully client-side, no install

What did you find?

Add reproduction steps (optional)