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.
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.
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.
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.
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.
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.
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.
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.
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".