Transport-Layer Congestion Control: Why TCP Must Manage It Even Though the Network Layer Is “Responsible”
Transport-Layer Congestion Control: Why TCP Must Manage It Even Though the Network Layer Is “Responsible”
Congestion is fundamentally a shared resource problem: many flows compete for finite router bandwidth, buffers, and link capacity. Although routers and the IP layer are where queuing happens, the end hosts implement transport-layer congestion control because only they can reliably infer path-level congestion signals and decide how to change sending rates in a coordinated, end-to-end way.
In classic internet design, the network layer provides a best-effort service and generally does not expose a rich, standardized “congestion state” API to transport protocols. Therefore, transport protocols must do congestion control using what they can observe at the endpoints—e.g., acknowledgments, losses, and round-trip timing—to approximate the state of the path.
Key ideas:
- Congestion control is often implemented end-to-end.
- End-to-end principle suggests endpoints can best manage correctness and performance tradeoffs.
- Congestion window (cwnd) is TCP’s primary mechanism for controlling how aggressively it injects traffic.
- UDP is intentionally minimal: it does not define a congestion-control contract.
This is why TCP contains congestion control logic, even though the consequences of congestion are created in the network layer (queues and drops). Transport protocols add measures because the network layer alone usually can’t provide sufficiently actionable feedback or guarantees to each sender.
Mermaid overview of responsibility boundaries:
Important constraint: In this environment, I’m currently unable to run the required web searches to attach verifiable citations to each major technical claim. The explanations below are based on standard networking theory and protocol design, but they cannot include the mandatory source footnotes.
TCP Congestion Control (High-level) — What cwnd/ACK loss mean
Why congestion control belongs (primarily) at transport endpoints
1) Network layer is best-effort and doesn’t provide per-flow congestion APIs
Routers can detect and react to congestion locally (e.g., queue management, dropping/marking). But transport protocols need per-connection rate decisions: how quickly can this sender transmit without causing persistent overload along its particular path?
Routers typically do not give TCP senders an explicit “current safe sending rate” for each flow. TCP therefore uses end-observed signals:
- Round-trip time (RTT) changes as queues grow.
- Packet loss (including ACK loss) indicates overload or path issues.
- ACK spacing and timing provide indirect feedback about whether the network is draining fast enough.
Thus, congestion control is an adaptation loop:
- Senders transmit.
- The network reacts (queueing → delay, drops).
- End hosts infer congestion from observations.
- End hosts change their future sending rate.
This loop naturally fits transport because it can be implemented per connection and per flow, using information available to endpoints.
2) The transport layer can control injection rate, which is the direct cause of congestion
Congestion is produced by offered load relative to capacity. Only the sender (transport endpoint) can directly reduce the rate at which it injects packets into the network.
Transport-layer congestion control modifies:
- how much data is “in flight” at once (e.g., via cwnd),
- retransmission behavior,
- and pacing/recovery strategies.
TCP’s congestion window acts like a distributed throttle: multiple flows competing through the same bottleneck adapt their rates (eventually converging to a stable operating point).
3) Intermediate nodes are shared: routers must protect everyone, but they can’t optimize each flow
Routers can implement queue management policies that affect all flows. However:
- they may not know per-flow semantics needed for safe optimization,
- they would need to maintain complex per-flow state,
- and doing fine-grained control at routers risks complexity and scaling problems.
Transport’s approach is “lightweight in routers, intelligence at endpoints”: routers apply simple queuing/drop/marking; endpoints adapt.
How TCP uses end-host signals to infer and react to congestion
- 1Step 1
TCP limits outstanding data using cwnd, preventing unbounded injection when the network starts to queue.
- 2Step 2
As packets flow, ACK arrivals (spacing and timing) and RTT samples reflect whether the path is draining fast enough.
- 3Step 3
TCP treats certain loss events (and, by design, ACK/timeout signals) as evidence of congestion, not just random errors.
- 4Step 4
TCP reduces cwnd and enters recovery, then probes for available capacity using its congestion-avoidance logic.
- 5Step 5
After successful transmissions, cwnd growth resumes gradually, balancing throughput and stability.
Why TCP has congestion control but UDP does not (by default)
1) UDP’s design goal is minimalism: it provides no reliability or delivery semantics
UDP is intentionally “thin”: it does not guarantee ordering, delivery, or retransmission. Because UDP doesn’t define a connection state machine in the same way TCP does, there is no standardized place for a connection-level congestion window to live.
So UDP faces a fundamental contract mismatch:
- TCP includes a feedback-driven control loop because it manages reliability and in-flight data.
- UDP leaves delivery semantics to the application and does not standardize a congestion-control loop.
2) Adding congestion control to UDP would require choosing an algorithm and interfaces
TCP congestion control is a specific, standardized algorithm suite (e.g., slow start, congestion avoidance, loss-based inference). For UDP to “also do congestion control,” either:
- the UDP protocol would need to define a congestion-control mechanism (and corresponding feedback signals), or
- each application would implement its own variant (leading to fragmentation and inconsistent behavior).
The Internet chose a modular approach: keep UDP generic; allow applications that care about rate control to implement it (or use UDP-based frameworks that include congestion control).
3) Some real-time applications intentionally prefer timeliness over throughput fairness
For many UDP use-cases (e.g., real-time media), retransmitting on loss may be harmful: late packets are less valuable than fresh ones. Congestion control is still relevant, but the objective function changes:
- TCP maximizes reliable delivery with rate adaptation.
- Real-time apps might minimize latency and jitter, sometimes tolerating loss while still trying to avoid congestion collapse.
That said, modern practice often uses UDP with additional logic (in the application layer) to implement congestion-aware behavior.
4) There are UDP-based congestion-controlled protocols—but they are not “plain UDP”
While UDP itself doesn’t standardize congestion control, there exist transport-like protocols built on top of UDP that do include congestion control and reliability-like features (e.g., QUIC). The key point: congestion control is implemented by higher-level protocol logic, not by raw UDP.
type="tip" title="Pro Tip" content="When reasoning about congestion control, focus on the control loop: endpoints observe feedback and change send rate. IP routers mainly enforce/reflect congestion; transport endpoints regulate the offered load."
type="warning" title="Warning" content="Loss is not always congestion. Wi-Fi interference, route changes, and application bugs can cause drops too—TCP’s congestion inference is probabilistic, not omniscient."
Transport-layer congestion control vs network-layer congestion management
Even though congestion control “lives” at transport, congestion management begins in the network layer:
- queues grow in routers/switches,
- buffering policies decide what gets dropped/marked,
- drops propagate as loss signals to endpoints.
A useful way to see the split:
- Congestion management is local and relatively policy-driven.
- Congestion control is strategic and end-to-end.
Mermaid conceptual diagram:
End-to-end congestion-control lifecycle (typical TCP behavior)
Slow start
1. StartTCP increases cwnd rapidly until it detects congestion signals."
Congestion avoidance
2. ProbeTCP increases more conservatively, seeking the bottleneck’s usable capacity."
Loss-based reduction
3. ReactOn congestion signals, TCP reduces cwnd and retransmits as needed."
Continue after recovery
4. RecoverTCP resumes probing with a safer cwnd until conditions improve."
Where responsibilities typically sit (conceptual)
Transport endpoints and routers both contribute to congestion outcomes, but in different roles.
Key misconceptions and edge cases
Knowledge Check
Why does TCP implement congestion control largely at the transport endpoints rather than relying only on the network layer?
Explore Related Topics
Responsibilities of the First Four Layers of the OSI Model
TCP/IP Networking: The Architecture of the Internet
This course covers the TCP/IP suite’s four‑layer architecture, key protocols, connection setup, addressing, and security considerations.
- Each TCP/IP layer adds its own header via encapsulation, moving data from a process to the physical medium.
- TCP is reliable and connection‑oriented; UDP is fast, connectionless with a small 8‑byte header.
- The 3‑way handshake uses SYN, SYN‑ACK, then ACK to establish a TCP connection.
- IPv4 uses 32‑bit addresses; IPv6 uses 128‑bit, and subnet masks define network vs host bits.
- Ports 0‑1023 are well‑known (e.g., 80 for HTTP); IP spoofing is a security threat.
Network Delays in Computer Networks + End-to-End Delay Calculation (200 MB over 1 Gbps with 3 Routers)