# HTTP2 window update and priority

**URL:** <https://www.ruby-forum.com/t/http2-window-update-and-priority/244591>\
**Category:** NGINX\
**Created:** [May 9, 2016, 3:27pm UTC](https://www.ruby-forum.com/t/http2-window-update-and-priority/244591 "2016-05-09T15:27:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [May 9, 2016, 3:27pm UTC](https://www.ruby-forum.com/t/http2-window-update-and-priority/244591/1 "2016-05-09T15:27:53Z")

</div>

Hi

According to my view on the source code of Nginx 1.9.15, I noticed some  
observation below:

1. when there is no enough window, nginx won’t send back the response  
frame, though according to the log, nginx said it has sent the headers  
frame out, but client won’t receive it. This is not right according to  
RFC  
7540 because window update will only limit the data frames

2.when there is no enough window, nginx will first store the request in  
the  
queue, when it received a window update, nginx will start fetch the  
streams  
stored in the queue use ngx\_queue\_head within a while loop(line 2161 in  
ngx\_http\_v2.c). I noticed the stream order I got is the same as the  
sending  
order with no relationship of the dependency tree, then nginx will  
create  
the corresponding data frames according to the stream order. But I  
noticed  
whether nginx will put the frame into the output queue depends on the  
value of wev-\>ready, here a problem is that I noticed when the request  
files is big, the wev-\>ready is set 0, only when this happens, the  
priority  
mechanism can work otherwise the frame will be sent out directly with no  
dependency observation. I am still confused on how does nginx implement  
the  
priority. Could you please give me some suggestions.

A failed priority mechanism example debug log:

> <https://github.com/valour01/LOG/blob/master/example.log>

Best Regards  
Muhui Jiang

---

<div class="post-metadata">

**Author:** ![Muhui\_Jiang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/eada6e/32.png) [@Muhui\_Jiang](https://www.ruby-forum.com/u/Muhui_Jiang)\
**Post date:** [May 10, 2016, 3:15pm UTC](https://www.ruby-forum.com/t/http2-window-update-and-priority/244591/2 "2016-05-10T15:15:46Z")

</div>

On Monday 09 May 2016 21:27:31 Muhui Jiang wrote:

> Hi
> 
> According to my view on the source code of Nginx 1.9.15, I noticed some  
> observation below:
> 
> 1. when there is no enough window, nginx won’t send back the response  
> frame, though according to the log, nginx said it has sent the headers  
> frame out, but client won’t receive it. This is not right according to RFC  
> 7540 because window update will only limit the data frames

You’ve misread the source code. HTTP/2 windows are handled in  
ngx\_http\_v2\_send\_chain(), which is only called for response body  
data.

> dependency observation. I am still confused on how does nginx implement the  
> priority. Could you please give me some suggestions.
> 
> A failed priority mechanism example debug log:  
> [LOG/example.log at master · valour01/LOG · GitHub](https://github.com/valour01/LOG/blob/master/example.log)

The prioritization has effect when there is concurrency for  
connection. In your case from nginx point of view there was  
only one stream in processing at any moment. The previous  
stream was completed before the new one has been received.

wbr, Valentin V. Bartenev

---

<div class="post-metadata">

**Author:** ![Muhui\_Jiang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/eada6e/32.png) [@Muhui\_Jiang](https://www.ruby-forum.com/u/Muhui_Jiang)\
**Post date:** [May 10, 2016, 4:13pm UTC](https://www.ruby-forum.com/t/http2-window-update-and-priority/244591/3 "2016-05-10T16:13:37Z")

</div>

Hi

> You’ve misread the source code. HTTP/2 windows are handled in  
> ngx\_http\_v2\_send\_chain(), which is only called for response body  
> data.

when the window is blocked, Nginx logs that the headers frame has been  
sent  
out, however I cannot receive any response headers. The same client  
tried  
on h2o and I can receive the response headers.

> The prioritization has effect when there is concurrency for  
> connection. In your case from nginx point of view there was  
> only one stream in processing at any moment. The previous  
> stream was completed before the new one has been received.

Let me explain my strategy in detail. I used some requests(stream id  
1-15)  
to consume the window (65535) And then block the window without sending  
any  
window update frame(I have sent a very large stream update before). Then  
I  
send the next 6 streams with different priorities. At this moment, the 6  
streams should be blocked. Nginx should have enough time to handle the  
priority. Then I send a very large window update frame, but nginx will  
process the stream one by one with no priority observation. What I want  
to  
say is, only when the file is really large then the priority can be  
observed. But I have give enough time to Nginx by block the request.  
Nginx  
should handle the priority though the file is really small. If you need  
more information, please tell me. Many Thanks

Best Regards  
Muhui Jiang

2016-05-10 21:15 GMT+08:00 Valentin V. Bartenev [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![Muhui\_Jiang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/eada6e/32.png) [@Muhui\_Jiang](https://www.ruby-forum.com/u/Muhui_Jiang)\
**Post date:** [May 10, 2016, 5:12pm UTC](https://www.ruby-forum.com/t/http2-window-update-and-priority/244591/4 "2016-05-10T17:12:02Z")

</div>

Hi

To say more, I may need your comment on my understanding of Nginx

1. Is the reason that I cannot receive the response headers frame  
because  
the response headers are stored in the SSL buffer?

2.Nginx will fetch the blocked request in the queue when receiving a  
window  
update frame (is the request order in the queue the same as my sending  
order?)

3.Then Nginx will handle the request one by one in a non-block mode. I  
noticed that when the requested file is small, nginx will create all the  
data frames, push the data frames into out frames queue and sent it out.  
(  
the handling order is the same as my sending request order) When the  
requested file is large(say 10Mb), nginx will create only a part of data  
frames and then create some other data frames (the handling order is  
related to the dependency tree). So:

- when a file is large, how many data frames to be generated once before  
generating the other frames, is it related to the SSL buffer size and  
the  
maximum frame size? and when Nginx are going to send out the frames  
and  
start a new SSL buffer.
- I dig the debug log and noticed the real process to reflect the  
priority  
handling is the order to generate the data frames and connect those  
data  
frames before sending then out. I cannot find the handling process  
related  
to priority when generating the data frames and connect them together.  
It  
would be great if you can tell me the strategy or locate the source  
code.
- Like the case I mentioned above. when the requested file is small,  
clients can not get the expected receiving response order. How large a  
file  
should be then nginx can handle them concurrently. I think in the real  
environment, many js , css file are not so big. So Nginx can not give  
priority mechanism in those cases. I suggest that Nginx should change  
the  
request queue order(Here I noticed the request queue is the same as the  
receiving order) rather than handling priority when generating data  
frames,  
it would be too late. So that even the files is small, the response  
order  
will also follows the dependency tree.

Best Regards  
Muhui Jiang

2016-05-10 22:33 GMT+08:00 Valentin V. Bartenev [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![Muhui\_Jiang](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/eada6e/32.png) [@Muhui\_Jiang](https://www.ruby-forum.com/u/Muhui_Jiang)\
**Post date:** [May 10, 2016, 4:34pm UTC](https://www.ruby-forum.com/t/http2-window-update-and-priority/244591/5 "2016-05-10T16:34:03Z")

</div>

On Tuesday 10 May 2016 22:12:59 Muhui Jiang wrote:

> Hi
> 
> > You’ve misread the source code. HTTP/2 windows are handled in  
> > ngx\_http\_v2\_send\_chain(), which is only called for response body  
> > data.
> 
> when the window is blocked, Nginx logs that the headers frame has been sent  
> out, however I cannot receive any response headers. The same client tried  
> on h2o and I can receive the response headers.

In addition, nginx uses SSL buffer to optimize record sizes.

You can tune it using the “ssl\_buffer\_size” directive:

> **[Module ngx\_http\_ssl\_module](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size)**
>
> The ngx\_http\_ssl\_module module provides the necessary support for HTTPS.

> priority. Then I send a very large window update frame, but nginx will  
> process the stream one by one with no priority observation. What I want to  
> say is, only when the file is really large then the priority can be  
> observed. But I have give enough time to Nginx by block the request. Nginx  
> should handle the priority though the file is really small. If you need  
> more information, please tell me. Many Thanks

[..]

Ok, now I understand your case. You are right, currently in this  
particular case priorities aren’t handled.

wbr, Valentin V. Bartenev
