Confused about sending requests in HTTP1 and HTTP2
Asked Answered
A

2

7

I learned that under HTTP1.1, the max number of default simultaneous persistent connections per host name (origin?) is going to be 6, at least for chrome. I am not asking about the exact number of the limit since I know it varies from browser to browser. I am more curious about when we will open a new connection for new requests - does the browser reuse the same TCP connection somehow or it always starts a new TCP connection unless if it hasn't reached the limit of concurrent requests?

Let's say we are using HTTP1.1 and we have Connection: Keep-Alive if in the html we have

<script src="https://foo/foo1.js"></script>
<script src="https://foo/foo2.js"></script>
<script src="https://foo/foo3.js"></script>
<script src="https://foo/foo4.js"></script>
<script src="https://foo/foo5.js"></script>
<script src="https://foo/foo6.js"></script>
<script src="https://foo/foo7.js"></script>

will each one of the scripts result in a new TCP connection established or all the subsequent requests will reuse the first TCP connection established by the first script tab? And if each one of these script result in a new TCP connection established, given the browser's limit for concurrent requests being 6, does the 7th request have to wait until the 6th request to be finished in order to establish the connection?

The above example is about initiating requests from HTML tags. What about api calls made from JavaScript? Let's in our javascript we have

const result1 = apiCall1()
const result2 = apiCall2()
const result3 = apiCall3()
const result4 = apiCall4()
const result5 = apiCall5()
const result6 = apiCall6()
const result7 = apiCall7()

And assume the endpoint that those API calls are hitting is all api.foo.com/v1/tasks, my questions are, again: will each one of the api call result in a new TCP connection established or all the subsequent requests will reuse the first TCP connection established by the first api call? And if each one of these api call result in a new TCP connection established, given the browser's limit for concurrent requests being 6, does the 7th request have to wait until the 6th request to be finished in order to establish the connection?

My last question is, compared to http1.1, does http2 address this problem by allowing sending many requests at the same time over one single TCP connection?

Atmospheric answered 5/12, 2021 at 20:25 Comment(4)
I think those requests should pipeline all down the same TCP connection, one after the other. And yes, HTTP/2 explicitly allows multiple requests/responses at the same time over one connection without having to worry about head-of-line blocking. That is, foo7.js could finish before foo1.js, and this would be fine in HTTP/2. (Not that it matters much though in the way these script tags are loaded, because they all have to be loaded and executed in-order anyway. Consider using modules!)Jackiejackinoffice
@Jackiejackinoffice not sure if I understand this but if all of requests can pipeline all down the same TCP connection, in what scenarios would we max out the limit of concurrent requests implemented by the browser?Atmospheric
Not all servers allow for HTTP keep-alive. Also, I imagine Chrome might make multiple connections in some cases as an optimization... I haven't been following changes here which is why I didn't post as an answer. See also: https://mcmap.net/q/332759/-how-does-http2-solve-head-of-line-blocking-hol-issue/362536Jackiejackinoffice
Why? Unless you are actually implementing a browser, the question seems rather hypothetical (and if you are writing your own browser, the reasons for the contraints in HTTP/1.0 and 1.1 are not very relevant to the state of TCP/IP in 2021)Pomelo
S
4

will each one of the scripts result in a new TCP connection established or all the subsequent requests will reuse the first TCP connection established by the first script tab?

Yes it would download them one by one, and start to open up more TCP connections to do that, up to the maximum of 6. The 7th request would have to wait for one of the connections to free up before it could be downloaded.

But the reality is, that the first request may have finished by the time later TCP connections are opened so it might not quite reach the 6 limit for only 6 or 7 requests.

What about api calls made from JavaScript? Let's in our javascript

Exact same thing. Limit of 6 per origin. Though one thing to note is certain CORS requests sent without credentials effectively counts as another origin (even though it’s the same actual origin) and so get another 6 connections.

My last question is, compared to http1.1, does http2 address this problem by allowing sending many requests at the same time over one single TCP connection?

Basically yes. Not quite at the same time due to the way TCP works, but as near as possible. See my answer here: What does multiplexing mean in HTTP/2

Strom answered 5/12, 2021 at 23:40 Comment(2)
I don't think that this is how blocking <script> works. Script execution is blocked, but nothing prevents the browser to download it ahead of execution. I've just tried to add 4 scripts from the same origin cdnjs.cloudflare.com in <head>, and according to dev tools, Chrome initiates download at the same time, and they finish downloading in random order.Alb
That's a fair point. A script is render blocking, but not parser blocking. Well at least not lookahead parser. Will update the answer.Strom
E
1

The process is simple, if you assign keep-alive the connection is remembered for faster handshake so a user can make many requests without having to re-open a costly secure connection.

Now there will always be the syn/ack process to make requests with the server. For the server to respond to every item your user requested a new connection is needed. There's bypassing this a little with cache to help your bandwidth and lessen the requests to server. All connections are ended upon request served.

So in a scenario 100 browsers want to hit your site, each request looks like 1.js 2.js... The output should be in order but this can greatly depend on a lot of things. Your language you're coding in server-sided, how it's handled, serves and if you manage any queues. If you make a request that requires longer processing (will get back to you in the future) other requests could go ahead as long as you're not blocking the event loop (comes down to your server).


Below you can see the process to establish a connection to the server, this is engaged each and every request. The cost to TLS can be improved but initial request is expensive. How it works.

Eozoic answered 18/12, 2021 at 13:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.