The short answer

Flow control protects the receiver, while congestion control protects the network path. Both of them run inside the TCP sender, though. RFC 5681 settles the relationship in one line: “The minimum of cwnd and rwnd governs data transmission.” The receiver advertises rwnd, whereas the sender computes cwnd on its own. So the popular exam answer separates the two by OSI layer. That answer describes flow control as a general idea, rather than TCP’s flow control. What really separates them is the thing each one is protecting.

A TCP sender can send too fast for two entirely different reasons. Either the receiver cannot keep up, or the path between them cannot. Flow control handles the receiver case, while congestion control handles the path.

This guide reads the two governing RFCs directly. RFC 5681 defines TCP’s congestion control, and RFC 9293 defines the window that flow control rides on. Where the popular comparison tables disagree with those documents, the RFC wins here.

Diagram showing flow control protecting the receiver buffer with the advertised window rwnd and congestion control protecting the network path with the congestion window cwnd
Flow control guards the receiver’s buffer; congestion control guards the path between the hosts.

What Each One Actually Protects

Start with the two variables, since everything else follows from them. RFC 5681 defines both of them in a single paragraph. The congestion window is “a sender-side limit on the amount of data the sender can transmit into the network”.

The advertised window is its mirror image. That mirror is “a receiver-side limit on the amount of outstanding data”. The pair therefore differs in who the limit is guarding. One protects a buffer, whereas the other protects a path.

Flow control looks after the receiver. A fast server can produce data quicker than a small client reads it, and the client’s buffer would then overflow. Therefore the receiver publishes a number that caps what the sender may leave outstanding.

Congestion control looks after everything between the two hosts. Routers hold queues, and those queues are finite. When too many senders push at once, the queues fill and routers drop packets.

Both limits bind at the sender, though only one of them originates there. The receiver advertises its window, while the sender computes its own. TCP can track either number because it is connection oriented, a model our connection oriented vs connection less guide covers.

How Flow Control Works

TCP flow control is a single number, repeated constantly. Every segment carries a window field, and RFC 9293 gives that field 16 bits.

The meaning of the field is the receiver’s own accounting. It counts the data octets that “the sender of this segment is willing to accept”. In other words, the receiver states how much room remains.

RFC 9293 then ties that number to memory. The advertised window is “related to the data buffer space currently available for this connection”. Flow control is buffer arithmetic rather than path arithmetic.

Nothing forces the receiver to be generous, either. RFC 9293 notes that “Indicating a large window encourages transmissions”. A small window does the opposite, because it throttles the sender directly.

Ignoring the window has a defined consequence. “If more data arrives than can be accepted, it will be discarded.” The waste does not stop there. “This will result in excessive retransmissions, adding unnecessarily to the load on the network and the TCP endpoints.”

The window can also reach zero, which halts the sender completely. A receiver “MAY keep its offered receive window closed indefinitely”, so that pause has no time limit. Therefore the sender probes, and “Probing of zero (offered) windows MUST be supported”.

Zero-window probing exists for one reason. Without it, a reopened window might never reach the sender. The probe guarantees “the reopening of the window will be reliably reported to the other”.

How Congestion Control Works

RFC 5681, titled TCP Congestion Control, is the standard here. It reached standards track in 2009, and it obsoletes RFC 2581.

Congestion control answers a harder question. A sender always knows the receiver’s window, because the receiver keeps sending it. Nobody, however, mails the sender a number for the path.

So TCP guesses, then corrects. Opening a connection into unknown conditions “requires TCP to slowly probe the network to determine the available capacity”. The congestion window holds that running estimate.

Ownership of the algorithm is not shared. “The slow start and congestion avoidance algorithms MUST be used by a TCP sender”. That control covers “the amount of outstanding data being injected into the network”.

The RFC also fixes a ceiling rather than a floor. A sender may be “more conservative than the algorithms allow”. It may not be rougher, though: “a TCP MUST NOT be more aggressive than the following algorithms allow”.

UDP has no equivalent machinery. A UDP datagram carries no window field and no congestion window, so nothing throttles it by default. Our TCP vs UDP guide covers what that trade buys and costs.

Flow Control vs Congestion Control: Comparison Table

Infographic comparing flow control and congestion control on what each protects, the governing variable, who sets it, the signal it reacts to and the governing formula
Flow control vs congestion control at a glance: what each protects, which window it uses, and how the two combine.

The table below sets the two mechanisms against each other, row by row. Every value traces back to RFC 5681 or RFC 9293.

AspectFlow controlCongestion control
What it protectsThe receiver’s bufferThe network path between the hosts
Governing variablerwnd, the receiver windowcwnd, the congestion window
Who sets the valueThe receiver advertises itThe sender computes it instead
Where it is enforcedAt the senderAt the sender
RFC 5681’s own wording“a receiver-side limit on the amount of outstanding data”“a sender-side limit on the amount of data the sender can transmit into the network”
Does the value travelYes, in the window field of every segmentNo, since it never leaves the sender
Problem it preventsOverrunning a slow receiverOverloading the path
What its absence risksDiscarded data, then excessive retransmissionsA sender “more aggressive than the following algorithms allow”
Layer inside TCPTransport, at the senderTransport, at the sender
Layer outside TCPAlso a data link idea between adjacent nodesRouters queue, drop and can mark ECN
Do routers run the algorithmNoNo, though they do generate the signal
Signal it reacts toThe advertised window in incoming ACKsLoss, and optionally ECN per RFC 3168
Scope in TCPEnd to endEnd to end as well
Governing formulamin(cwnd, rwnd)min(cwnd, rwnd)
Defining RFCRFC 9293RFC 5681
Named algorithmsWindow advertisement, zero-window probingSlow start, congestion avoidance, fast retransmit, fast recovery
State that drives itThe receiver’s free buffer spacessthresh, which picks the active algorithm
On a slow receiverrwnd shrinks, and it can reach zeroUnaffected on its own
On a congested pathUnaffected on its owncwnd falls, then climbs back
How the two interactWhichever window is smaller governsWhichever window is smaller governs

One row carries the whole article: the row for where each limit binds. Both cells read the same way, at the sender. That is exactly what the layer-based comparisons miss.

The Layer Claim That Does Not Hold

Diagram showing cwnd and rwnd both stored in the sender's per-connection state and combined as the minimum of the two, with routers only supplying loss and ECN signals
Both limits sit in the same sender, in the same computation: the minimum of cwnd and rwnd governs transmission.

Almost every comparison page separates the two by OSI layer. Flow control gets filed under the data link layer, while congestion control gets the network layer. That split is half right, and the wrong half does real damage.

Here is the half that holds up. Flow control as a general idea genuinely does live at the data link layer. Stop-and-wait and sliding-window schemes run between two adjacent nodes, as our Go-Back-N vs Selective Repeat guide shows. Nobody should mark that wrong in an exam.

Now the half that fails. Those pages are describing TCP rather than a link protocol. RFC 9293 calls TCP “an important transport-layer protocol in the Internet protocol stack”. Its flow control and its congestion control therefore sit in one layer.

They also sit in the same host and the same block of state. RFC 5681 says “two variables are added to the TCP per-connection state” for these algorithms. Those two variables are cwnd and rwnd.

Then comes the arithmetic, which is the strongest evidence available. “The minimum of cwnd and rwnd governs data transmission.” One expression, one sender, both limits.

So the error is not the data link claim. The error is treating layer as the axis that separates the two. In TCP they share a layer, a host and one computation. What actually separates them is the thing each one protects.

Routers are not spectators here, mind you. They queue, they drop, and they can mark packets under the ECN scheme of RFC 3168. Yet no router runs TCP’s congestion control, because RFC 5681 assigns those algorithms to the sender.

Layer maps still matter for other purposes, and our OSI model vs TCP/IP model guide covers those. Use them to place protocols, though, and not to separate rwnd from cwnd.

How the Two Combine in One Sender

RFC 5681 states the combination twice. The definitions section gives the long form, and section 3.1 gives the short one.

The short form is the sentence to memorise. “The minimum of cwnd and rwnd governs data transmission.” Nothing in the standard lets one variable override the other.

The long form spells out the bookkeeping. Data must stop at “the sum of the highest acknowledged sequence number and the minimum of cwnd and rwnd”. The smaller window therefore sets the edge, whichever one that happens to be.

Neither number wins permanently, either. The congestion window changes every round trip, while the advertised window changes whenever the receiving application reads. A connection can be receiver-limited early and network-limited later, or the reverse.

A zero window shows how absolute the rule is. When rwnd reaches zero, no congestion window helps at all. The sender simply waits, and it probes until the receiver reopens.

Both numbers belong to one connection’s state at the sender. TCP therefore has to remember them between segments, unlike a stateless protocol. That per-connection memory is what makes the pair workable.

The Four Algorithms TCP Actually Defines

Many summaries name slow start and congestion avoidance, then stop. RFC 5681’s abstract names twice that many.

Its opening sentence carries the whole scope. “This document defines TCP’s four intertwined congestion control algorithms: slow start, congestion avoidance, fast retransmit, and fast recovery.”

Read the word “intertwined” carefully, since it is the RFC’s own choice. These are not four options to pick between. They hand control to each other inside a single connection.

One variable separates the middle two. RFC 5681 introduces ssthresh “to determine whether the slow start or congestion avoidance algorithm is used”. Slow start runs below that threshold, whereas congestion avoidance runs above it.

The threshold starts out of the way on purpose. “The initial value of ssthresh SHOULD be set arbitrarily high”, so a new connection begins in slow start. Congestion then pulls the threshold down.

Fast retransmit handles loss without waiting for a timer. “The fast retransmit algorithm uses the arrival of 3 duplicate ACKs”. Those duplicates count “as an indication that a segment has been lost”.

Fast recovery then takes over immediately. It “governs the transmission of new data until a non-duplicate ACK arrives”. The sender keeps moving, although on a reduced congestion window.

How Congestion Gets Detected

Textbooks usually say that packet loss is the congestion signal. RFC 5681 is more careful than that.

Its algorithms do work “using loss as the signal of congestion”. The document then widens the picture in the very next sentence. “Explicit Congestion Notification (ECN) could also be used” as RFC 3168 specifies.

So loss is the signal these particular algorithms use, rather than the only signal available. That distinction matters in interviews. ECN lets a router flag congestion before it has to drop anything.

TCP spots loss two ways, and RFC 5681 covers both. The retransmission timer catches it slowly, while three duplicate ACKs catch it quickly. Fast retransmit exists precisely to avoid waiting for the timer.

Either way, the reaction is the same in kind. A sender in fast recovery keeps transmitting on a reduced window, “since loss is an indication of congestion”. Caution, in short, is the standard’s default posture.

Which One Is Your Bottleneck

On a live connection, only one of the two limits binds at a time. Working out which one it is changes what you fix.

One of them is visible on the wire. The receive window travels in the header of every segment, so a packet capture shows it. The congestion window never leaves the sender. RFC 5681 calls cwnd “A TCP state variable that limits the amount of data a TCP can send”.

Small advertised windows point at the receiver. The field itself holds 16 bits, though “The value is shifted when the window scaling extension is used”. Without that extension, the field alone caps how much data can be outstanding.

A window that reaches zero is clearer still. The receiving application is not draining its buffer, and no sender-side change fixes that. RFC 9293 lets the receiver hold the window closed indefinitely.

Loss and retransmissions instead point at the path. The congestion window is the limit that falls in that case, so receiver tuning will not help. Our latency vs throughput guide explains why the resulting throughput drop is not a latency problem.

The honest summary is short. Compare the two windows, and then treat the smaller one as the thing to work on.

Interview Questions

Flow control protects the receiver’s buffer through rwnd. Congestion control protects the network path through cwnd, and the sender enforces both limits.

Not inside TCP. Both are sender-side transport functions, because RFC 5681 combines them as the minimum of cwnd and rwnd. Flow control does also exist at the data link layer as a general idea.

Whichever window is smaller. RFC 5681 puts it in one line: “The minimum of cwnd and rwnd governs data transmission.”

Slow start, congestion avoidance, fast retransmit and fast recovery. RFC 5681 calls them four intertwined algorithms rather than four alternatives.

Not quite. These algorithms work using loss as the signal. RFC 5681 notes, though, that ECN could also be used, as RFC 3168 specifies.

Frequently Asked Questions

Flow control stops a sender from overrunning the receiver’s buffer, using the advertised window rwnd. Congestion control stops that same sender from overloading the network path, using the congestion window cwnd.

Inside TCP they are not. Both run at the sender in the transport layer, and RFC 5681 combines them in one expression. Flow control does also exist as a data link idea between adjacent nodes. That is where the layer answer comes from.

Whichever one is smaller at that moment. RFC 5681 states it plainly: “The minimum of cwnd and rwnd governs data transmission.” Neither variable wins permanently, so the binding limit shifts during a connection.

The sender does. RFC 5681 calls cwnd a sender-side limit, and the value never travels on the wire. The receiver advertises rwnd instead, in the window field of every segment.

Four of them. RFC 5681 names slow start, congestion avoidance, fast retransmit and fast recovery, and it calls them intertwined rather than alternative.

Not necessarily. RFC 5681’s algorithms use loss as the signal of congestion. The same document notes, though, that ECN could also be used, as specified in RFC 3168.

The sender stops sending new data and starts probing. RFC 9293 requires support for zero-window probing, so the reopened window gets reported reliably.

No, because a UDP datagram carries neither a window field nor a congestion window. Any pacing therefore has to come from the application above it.

Wrapping Up

The two mechanisms answer different questions. Flow control asks whether the receiver can absorb more, while congestion control asks whether the path can carry more. RFC 5681 keeps both answers in one place, at the sender.

Remember the arithmetic rather than the layer diagram. The minimum of the two windows governs transmission, so the binding limit shifts as conditions change. That single line settles most of the exam questions on this topic.

Related reading on DiffStudy:

Whatsapp-color Created with Sketch.

By Arun Kumar

Full Stack Developer with a BE in Computer Science, working with React, Next.js, Node.js, MongoDB, and AI/ML tools. Founder of DiffStudy — built to help CS students ace GATE and university exams, and keep developers up to date across AI, cloud, system design, web development, and every field of computer science. Every article is written from real hands-on experience, not just theory.

Leave a Reply

Your email address will not be published. Required fields are marked *


You cannot copy content of this page