Network congestion occurs when traffic exceeds link or buffer capacity, causing packet loss and increased latency. TCP congestion control algorithms (Cubic, BBR, Reno) dynamically adjust sending rate to avoid overwhelming the network. Persistent congestion degrades all traffic on the shared path.
Congestion happens when the aggregate traffic on a link exceeds its capacity. Router buffers fill, queuing delay increases, and eventually packets are dropped. TCP detects congestion through packet loss (timeout or triple duplicate ACKs) and reduces its congestion window (cwnd) to lower the sending rate. The congestion control algorithm determines how aggressively the sender probes for available bandwidth and how quickly it backs off. Cubic (Linux default) uses a cubic function to grow cwnd. BBR (Google's algorithm) estimates bandwidth and RTT directly rather than relying on loss signals. Bufferbloat occurs when oversized router buffers delay packets instead of dropping them – TCP cannot detect congestion, latency grows to seconds, and interactive traffic suffers. The solution is Active Queue Management (AQM) like CoDel or fq_codel.
Flow Control
Flow control prevents a fast sender from overwhelming a slow receiver. TCP uses a receive window (rwnd) advertised by the receiver to limit in-flight data. If the receiver's buffer fills, it shrinks rwnd to zero, pausing the sender until the application drains the buffer.
Packet Loss
Packet loss occurs when transmitted packets fail to reach their destination. Causes include congestion (buffer overflow), CRC errors (physical layer noise), and intentional drops (QoS policing, firewall rules). TCP retransmits lost packets automatically. UDP does not – the application must handle loss.