Why Http/2 is fast?

Devansh Gupta
Devansh Gupta
Published in
5 min readDec 19, 2023

--

While going for tea I asked my colleague Tanmaya Panda, Why is gRPC so fast? Here is the conversation we had.

Me: Why people are so obsessed with gRPC?

Tanmay: Because it’s fast, it has its own messaging format, ProtoBuf, developed by Google.

Me: Yeah! But Protobuf can’t be the sole reason for its performance, I mean it provides fast encoding and decoding because it’s a binary format. But what else is there which makes gRPC so fast?

Tanmay: The reason behind that is the Http/2 protocol.

Me: You mean Http (The Application Layer Protocol).

Tanmay: No, It’s an upgraded version of HTTP, which runs on TCP underneath.

Me: I see, But How does it make gRPC faster as we are using the same protocol on the transport layer as the normal HTTP?

Tanmay: Let’s add some formal notions here, The Http you are referring to is called Http 1.1, which is pretty old, It came in 1997, You might haven’t been born when it launched.

Me: Yeah! I was born in 1999.

Tanmay: Though Http1.1 fulfilled Web needs for a long period of time, we need something faster as the dependency on the web was continuously increasing. So the world needed a faster protocol and then came Http/2 in 2015. Actually, Google and other folks were experimenting with its optimizations for years with a substitute protocol named SPDY. All the popular browsers were supporting it.

Me: You must be good in History class, jokes apart but what was making Http1.1 slow?

Tanmay: No, It wasn’t slow but was not engineered to carry the amount of load and transactions we are having today. A simple webpage requires 20–30 resources to load at a time, which means making 20–30 HTTP requests at once, which would then create 20–30 TCP connections. Isn’t it too much?

Me: Yeah! But Http has a KeepAlive mechanism, You can use the same TCP connection across multiple requests.

Tanmay: Absolutely correct, We can re-use the same connection, but you can make the second request after completing the first one.

Me: But Http also has a Pipeline feature, you can bundle many Http requests at once, wouldn’t that help?

Tanmay: Seems you have done your homework. Pipelining can save us a lot of time, but your server would require to push response in the order of the request, e.g. for reqA, reqC, reqB it would require to send respA, respC, respB respectively.

Me: So what? how does it make the pipeline unfeasible, Our server can concurrently process the request and give us the response in the required order.

Tanmay: I agree, It can process the requests concurrently but it can’t send the second request’s response before the first request’s one, which means no matter how fast the server might process request 2, it would wait until it processes the first request and then respond with the second response. This problem is popularly known as “Head of Line Blocking”. Pipelining is also difficult to implement for network devices, like proxies, etc. So it’s not a widely accepted feature of Http1.1.

Me: Got it, Http1.1 is a mediocre protocol, but how does Http/2 solve these problems?

Tanmay: Again, It’s not mediocre but old for today’s use cases. Firstly, Http/2 works on a principle of making one TCP connection per origin, the origin is the hostname of the server.

Me: Cool, So on that single connection, does it do some kind of batch processing of the requests?

Tanmay: No, It provides something called “Multiplexing”, which means you can send multiple requests/responses on a single connection, bi-directionally. Bi-Directionally is an important notion here. This means both sides of the connection can send/receive data at the same time. This means If your webpage has 3 Javascript files, and 2 CSS files then your browser can dispatch 5 requests at once, and the server can respond in any order (i.e. as soon as it processes the requests), so no problem of Head of Line Blocking. Every such transaction is called a “Stream”.

Me: Got it, But how would the browser distinguish among multiple streams?

Tanmay: Here comes another new construct called, “Frames”. A Frame is like a data packet, which either can contain some metadata about the payload it contains and the payload. It can be multiple types Header Frame, Data Frame, Settings Frame, etc. Every Frame is length-prefixed, which means the first few bytes of the frame tell us about its size so that we can decode it properly, then it contains some frame-related flags and metadata and then it contains the payload.

Me: So, You are saying that it would have different frames for request headers and request data?

Tanmay: Correct, It would have different frames for the header and body and if one frame is too large, then it can break the frame into smaller frames. All of these fragmenting provides faster processing of data over a single connection and all these frames are Binary Encoded/Decoded so it makes it much faster than traditional HTTP messages which are text-based only. Http/2 also uses a compression algorithm named HPACK to compress the request/response header which further saves bandwidth and reduces latency.

Me: You look like a Fan Boy for Http/2, But it’s very cool. Any other feature You wanna highlight? Don’t say We can talk to Aliens over Http/2.

Tanmay: Not now, Maybe Http/4 would have that feature as well. It has a feature called, “Server Push”, where the server can push some data to the browser/client without them requesting it, in advance. Suppose you know a webpage gonna need some JS and CSS files, and the browser gonna request them next, you can then send those data to the client before he asks for it. The client can also reject that stream if he already has that data in the cache or for any other reason.

Me: Okay, So can we use it in place of Http-based Server Side Events?

Tanmay: No, As implementation of Server Push is kinda matter of research and it’s not made of SSE-like use cases.

Me: The world is changing faster.

Tanmay: Yeah! Like you finished your Tea and mine got Cold.

PS: I don’t drink Tea

Note: Not Generated by AI

References

--

--