Re: Overhead of HTTP/2 Stream Management.


I don't see much difference between the stream overheads of HTTP/2 vs the
connection overheads of HTTP/1.

Both need open/close state kept and even in HTTP/1 that state is moderately
complex as you can be half closed in and/or half closed out; the response
can complete before the request; there are multiple sources of events
(application vs network) that can race on state changes; the server has a
requirement to reliably deliver a serialised event stream to the
application without duplicates or loopbacks.    Unless the server/client
keeps good atomic state on the open/closed status, then there are going to
be lost events and/or leaked resources.

In jetty the vast majority of this state overhead is in common code used by
both HTTP/1 and HTTP/2.    This code used to be a lot simpler in older
versions of our HTTP/1 on server... but it was wrong code that missed many
edge cases when presented with fully asynchronous applications.   Closing
asynchronous streams is just complex and multiplexing changes that very
little. It just makes the network event stream look a little different and
some events are distributed to multiple listeners.


On 6 April 2015 at 06:08, Max Bruce <> wrote:

> The way HTTP works though, we don't need streams in such a conventional
> and TCP-like way. We only need multiplexed packets to carry data over, so
> just associate request/response pairs with an ID, and allow server push via
> server sending the request path in a header too. Why do we even need a
> frame structure? It's unnecessary overhead. Same with the virtual streams.
> On Sun, Apr 5, 2015 at 11:57 AM, Willy Tarreau <> wrote:
>> On Sun, Apr 05, 2015 at 11:45:53AM -0700, Max Bruce wrote:
>> > My thoughts is that you just don't use so much overhead. You don't get
>> rid
>> > of stream IDs, you just don't need so much complex things surrounding
>> it.
>> > Example: You append a header to HTTP/1.1 request, with a response ID,
>> > server responds with it. Server can push responses by sending a unsent
>> ID &
>> > request path in a header.
>> You still need the stream IDs in the frames themselves so that you know
>> which stream each frame belongs to.
>> Multiplexed systems always look simple at first, until you start to
>> implement them, cover the corner cases (eg: who closes first etc) and
>> you finally realize once everything is done how much your system looks
>> like tcp...
>> There was an elegant (in my opinion) simplification in H/2 compared to
>> other systems, the stream IDs are always incremented until the largest
>> encodable ID is reached, which is where a new connection must be used.
>> I find this elegant because you don't need to keep track of IDs in use
>> vs available ones and it really simplifies a number of things (eg: no
>> risk to have late frames from an old stream using the same ID).
>> It doesn't please me either to have to implement such a complex system
>> but I am absolutely convinced that it can hardly be simplified further
>> as long as we want non-blocking, multiplexed streams. I have already
>> implemented multiplexed streams in the past for some projects, and it
>> resulted in almost the same design (but more complex).
>> Willy

Greg Wilkins <>  @  Webtide - *an Intalio subsidiary* HTTP, SPDY, Websocket server and client that scales  advice and support for jetty and cometd.

Received on Sunday, 5 April 2015 23:15:33 UTC