This is a static archive of our old Q&A Site. Please post any new questions and answers at

Why does the receive window increase during the three-way handshake ?


hello I have a question about Tcp receive window size. I have this example from Wireshark:

client A :syn, win=8192, ws=4 ====> <===== server B: syn, ack win 5840, ws=128

client A : ack win=65700

1-How did we obtain 65700 (increase from 8192B to 65700B) in three way handshake? 2-how does the ws negotiotated in this example?


asked 14 Mar '16, 14:02

IBrahim%20El-Khalil's gravatar image

IBrahim El-K...
accept rate: 0%

edited 14 Mar '16, 14:46

Jim%20Aragon's gravatar image

Jim Aragon

2 Answers:


The window size is not negotiated but announced as each party has its own one - it is a receiving window so there is no reason why it should be negotiated as the sender can accommodate to any size announced. Why the client has increased the window size during initial handshake is an example of a question which Wireshark cannot answer. Packet capture and analysis can always tell you what has happened but only sometimes why it has happened.

E.g. we may assume that the TCP stack of the client uses some hardcoded window size value when sending the initial SYN packet and only uses the real value when it sends the first "useful" packet, but only analysis of the source code of the client's TCP stack and application can give the real answer.

What is negotiated is the support of window size scale factor. Until the client gets a confirmation from the server that the server supports window size scale factor as well (through presence of the ws option in the server's SYN, ACK packet), it does not know whether it may make use of it. So the window size value in the client's SYN packet is actually just a "safe side" one and the real value is only indicated when it becomes clear which way to specify it (with or without use of the ws factor).

Just to be clear: support of ws is negotiated, value of ws is not. Each side announces (and subsequently uses) its own ws value.

But this is still not an answer why the size indicated in the SYN packet was 8192 bytes and not, say, 65500 bytes, which would be closer to the "real" value announced later.

answered 14 Mar '16, 14:19

sindy's gravatar image

accept rate: 24%

edited 14 Mar '16, 15:13

what i've understood that wireshark cant give an interpretation of why the recive window increasing during the three-way handshak !!

(15 Mar '16, 03:43) IBrahim El-K...

Your understanding is correct, as said Wireshark cannot know the reasons why some packets look the way they do.

But in this particular case of TCP session establishment, the window size itself in the initial SYN packet has almost no practical meaning. So there may simply be no reason at all behind use of that particular value of 8192. If there is, RFC6528 should explain it.

(15 Mar '16, 04:11) sindy

@Ibrahim-el-khalil, more "!" do not cause more understanding on the receiving side.

What are you going to achieve, or what problem are you tracking?

The fact that the size of the receiving window grows and shrinks throughout the lifetime of the session is normal. MSS is a fixed value throughout the whole session as it is a property of the network path; window size is a dynamic value as it depends on the application behaviour: if the data have arrived fine to the receiving buffer of the tcp stack but the application doesn't fetch them from the buffer, the window size may decrease down to 0; as soon as the application fetches the data, the window will grow again. And this happens independently for each direction.

(15 Mar '16, 04:40) sindy

As far as i know the reason behind the first choice of initial window of 8192 it depends to the operating System (Window 7 take as default 8KB 8*1024=8192B),could we take the hypothesis of the BDP between the sender and the receiver ?

(15 Mar '16, 04:59) IBrahim El-K...

What means BDP here?

(15 Mar '16, 05:12) sindy

BDP=Bandwidth Delay product=RTT*Bandwidth (

(15 Mar '16, 05:32) IBrahim El-K...

Well, you could take a hypothesis that the TCP stack of the client has measured the time from sending its initial SYN packet to receiving the SYN, ACK from the server, and has used this single measured value of RTT to calculate the window size to be sent in its first ACK-only packet.

But my personal opinion is that such behaviour is not very likely, as such a single measurement is quite an unreliable base for any conclusion about the mid-term BDP on the network between the client and the server.

(15 Mar '16, 06:59) sindy

there are another hypothesis , After i have done a lot of tests with wireshark : i concluded a formula may be it will help us (if i am not mistaken , it works with all my tests) up((64kbx1024)/Host2.mss)xHost2.MSS it works with all my captures of three way handshak that's valide ?

(15 Mar '16, 09:26) IBrahim El-K...

Anything divided by a number and then multiplied by the same number (Host2.MSS in your case) remains effectively unchanged (leaving aside eventual loss of precision if fixed point or integer arithmetic is used), so either there is a mistake in your formula or it says the same as = 64 kB * 1024 which doesn't match you captured example.

I still don't understand what is your ultimate goal. To reverse engineer the rule which the client is using to determine the initial window size?

(15 Mar '16, 10:09) sindy

Concerning the above formula up (64x1024/1460)x1460 (mss=1460) =45x1460=65700B I want to link between the theory (TCP) and the practice .

(15 Mar '16, 13:04) IBrahim El-K...

If you replace 1460 with e.g. 730 in your formula, you'll get almost the same result. So why should the MSS be the magic constant if you'll get the same result using any other number between, say, 800 and 2000.

What is still not clear to me is how you could get a window size value of 65700 with a window scaling factor value of 4, because ws factor value of 4 translates into "multiply the 16-bit value of the window size field by 16 (2^4)". So the resulting value as shown by Wireshark should be divisible by 16, and 65700 isn't, it gives 4106.25. Can you post the packet or at least its hex dump?

(15 Mar '16, 13:17) sindy

that's the three way handshak of my example :

==> 63510→80 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=4 SACK_PERM=1

==> 80→63510 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460 SACK_PERM=1 WS=2

==> 63510→80 [ACK] Seq=1 Ack=1 Win=65700 Len=0

==> HTTP 404 GET / HTTP/1.1

==> TCP 60 80→63510 [ACK] Seq=1 Ack=351 Win=6912 Len=0

(15 Mar '16, 13:42) IBrahim El-K...

I don't need the high-level text, I need the pcap file containing the three initial packets, or at least screenshots of dissections of the first and third packet where the raw value of the window size would be visible.

(15 Mar '16, 14:00) sindy

here the three packets

syn alt text

syn ack alt text

ack alt text

(15 Mar '16, 14:16) IBrahim El-K...

OK, clear. I haven't noticed that Wireshark shows the result of 2^ws as ws value in the single-line output, so the 4 in the SYN packet really means "multiply by 4" and not "multiply by 2^4".

That explains the mystery, 65700 is of course divisible by 4.

(15 Mar '16, 14:35) sindy

Did you found any explanation to the mystery ?

(16 Mar '16, 10:21) IBrahim El-K...

My comment just above yours was the explanation :-)

(16 Mar '16, 10:53) sindy

We return to the same question why did the receive window increased from 8192 to 16425 (65700/ws=4)?

(16 Mar '16, 11:01) IBrahim El-K...

Forget about the 16425, 65700 is the correct size of the window in bytes which the client wanted to announce. The 16425 must be multiplied by 4, I was talking about divisibility only because I could not understand how any integer multiplied by 16 (i.e. 2^4) could give 65700.

The 8192 is a value with no real meaning so the 65700 is the first value which informs the server about the available receiving buffer size.

We return to the same question why did the receive window increase

And we return to the same answer: it is impossible to find out the exact rule which the client's TCP stack uses to choose the size of the receiving buffer by just monitoring a few sessions. There may even be no dynamic rule at all. If there is, only the author of the tcp stack knows it.

You may try to find out whether there is any dynamic rule by using some kind of network simulator (like e.g. dummynet) to imitate connections with different delays and see whether initial window sizes of sessions between the same client and server (same machines and same applications at both ends) look different depending on the delay.

Instead of the above, you may want to capture the setup of several real sessions towards servers in different parts of the world, see whether the delay between sending the client's SYN packet and reception of the server's SYN,ACK packet differs significantly between the sessions, and look whether this difference is somehow correlated to the window size which the client announces in its first ACK packet. But with different servers, other factor than the delay between the SYN and SYN,ACK may exist: you may also observe whether the window size announced by the server affects the window size announced by the client in its first ACK packet (ignore the window size in SYN, it will be the same in all cases).

(16 Mar '16, 13:38) sindy
showing 5 of 19 show 14 more comments


Besides all implemations about the window start algorithms, like slow start or so. The real question, from my point of view, in a scenario like this...:

(1)Client -> Server: SYN     Win=8192 WS=4
(2)Server -> Client: SYN,ACK Win=5128 WS=128
(3)Client -> Server: ACK     Win=65700 Why does Wireshark shows us in the Info column of the Frames (1) and (2) not the calculated Window Size, like we can see it in Frame (3)?

  • The window size in the SYN Packets is never scaled
  • The Window Scale Option(WS) may only be activated if both partners advertises these option
  • The SYN packets are the only location where the WS option may appear

answered 16 Mar '16, 14:09

Christian_R's gravatar image

accept rate: 16%

edited 16 Mar '16, 14:17

I agree with you , the answers of all your questions confirmed by (rf1323), i was asking about the increasing from 8192 to 16425(unscaled)? there are any determined way of how it is calculated ?

(16 Mar '16, 14:36) IBrahim El-K...

It is a little bit other question, but it looks to me like the slow start algorithm. The best hint I can give you is baseline your devices, because every manufacturer may have his own way to implement.

(16 Mar '16, 14:43) Christian_R

@Christian_R, I believe that the window size value in the client's SYN packet is irrelevant, because

  • servers which do and servers which do not understand the ws option would interpret the window size value differently

  • until receiving the first ACK from the client, the server should not send any payload (at least using currently valid rules), so the window size value received in the 3rd packet overrides the one from the SYN packet anyway

However, I have a mental problem with the SYN,ACK packet from the server, as common sense says that there is no reason why the server should not make use of the window scaling already there (the client has declared support of WS so as the server is declaring it too, why should it not use it already here, as the client may start sending payload right after sending its ACK(seq=1, ack=1) packet so the window size in server's SYN,ACK packet is already meaningful). And my reading of what RFC7323 says is the same: it states that the shift (scaling) must be used in all "segments" except <syn> ones (plural), however a few lines above it clearly distinguishes between <syn> and <syn,ack> segment, which to me implies that in <syn,ack>, the scaling must be used too.

So to me, the correct way would be that Wireshark would show the resulting value as a product starting already from the 2nd packet of the session, not the 3rd one. Do you agree with me, i.e. should I file a bug?

(16 Mar '16, 14:53) sindy

Irrelevant or not. It is from my point of view a theoretical thing. There is window size and she would be processed. For the SYN,ACK interpreation the RFC 1323 Page 8 states it clearly:
The Window field in a SYN (i.e., a <syn> or <syn,ack>) segment itself is never scaled.

(16 Mar '16, 15:07) Christian_R

And that's the point, I read the RFC1323 (or RFC7323 which uses the same wording in this part) differently. For me a "SYN,ACK segment" is not the same as a "SYN segment", as throughout the document the authors use these names in the meaning of "the 2nd handshake packet" and "the 1st handshake packet", respectively. Maybe we should ask the RFC authors what they had in mind?

(16 Mar '16, 15:20) sindy

the Slow start algorithm still is an hypothesis

(16 Mar '16, 15:27) IBrahim El-K...

@Christian_R, I've re-read the RFC7323 - yes, they use the exact phrase which you've quoted but I've somehow missed it before. So the fact that Wireshark displays the "raw" value for these two packets is correct, and I've probably misunderstood your whole post

Why does Wireshark show us in the Info column of the Frames (1) and (2) not the calculated Window Size...

(17 Mar '16, 04:09) sindy

Ok. Then we both think it is clearly defined, fine. But maybe one or another manufacturer has misread it, too. Who knows? But as you told before at the moment it not so important, it would be a little bit more important when it comes to fast TCP open. But that is a different story...

(17 Mar '16, 04:25) Christian_R
showing 5 of 8 show 3 more comments