Re: per stream (initial) flow window size

Interesting, thanks Patrick. Curious, when you say "small initial window",
what is the value that you're currently using? Looking at, it looks like its 64KB (aka,
kDefaultRwin)? Great to hear that [HEADERS, WINDOW_UPDATE] combo is working
out so far. Agreed, 8 bytes may not be much, but that's still 8 extra bytes
per stream. And if all the popular clients end up going with a strategy
like the one you've described, perhaps it's worth entertaining...

On Wed, Oct 9, 2013 at 10:21 PM, Patrick McManus <>wrote:

> Hey Ilya,
> So Firefox has been taking exactly this approach with both spdy/3.[+] and
> http/2 already. We use a small initial window setting that is meant to
> apply to pushes - and we reusme them in much the same manner as you
> describe. For pulls we want to use large windows so we simply pipeline a
> window update in the same SSL data record that contains the HEADER. While
> there is a theoretical race there it in effect can't actually be delayed
> because of the way SSL frames everything atomically; it hasn't ever been a
> problem and no servers have complained to me (yet) about the extra frame
> callback overhead. I actually expected to have some interop problems with
> this strategy in the early days - but it hasn't been a problem at all.
> So imo the use case is already well served by the draft as is.. what's
> left is whether saving 8 extra bytes for the pat/ilya use case is
> interesting and worth the complexity.. I'd be happy with it of course, but
> I don't realistically think it is necessary. ymmv.
> -P
> On Tue, Oct 8, 2013 at 4:14 PM, Ilya Grigorik <> wrote:
>> SETTINGS allows us to set a default starting window for all streams +
>> update this default later. However, I think there are compelling cases
>> where it would be beneficial to allow different streams to start with a
>> different initial window size (similar to optional priority in headers
>> frame). Given that this would effectively be a new feature... let me try
>> to motivate why the extra complexity is worth it based on some of the
>> recent work I've been involved with:
>> We want to make browser pre{fetch,rendering} smarter [1,2]. Meaning, we
>> want to be able to discover critical page resources as early as possible
>> and kick off fetches for those assets also. However, since some of these
>> assets are large (and there can be many of them), we need to control how
>> much data we fetch (e.g. if we are too aggressive we may slow down the host
>> page, and/or incur high overhead for the user).
>> A concrete example of this is the work we've been experimenting with in
>> PageSpeed [3], where we are aggressively inlining CSS/JS and even doing
>> "page splits": the rewriter effectively creates two pages, the first is the
>> "prefetch friendly" version which fits in < 15KB (one RTT), and second is
>> the diff that fills in the rest once the navigation is triggered via an XHR
>> -- if that sounds crazy, then that's not too far from the truth. That said,
>> we have a working prototype, and it's showing impressive results.. For
>> example, we can take a mobile wikipedia page, which currently takes 9s
>> (!!!) to first render (on a 3G profile), down to 1.6s [3] by using the
>> combination of prefetch + page split strategies.
>> What does flow control have to do this with all this? When issuing a
>> prefetch, we would like to be able to open a request with a lower initial
>> window (e.g. 15KB), and fetch just the head of the document - in most
>> cases, this will allow us to discover the critical resources, initiate
>> requests for them, etc. Then, if the navigation is triggered, we would just
>> increment the window and "resume" the stream to get the rest of the page...
>> This eliminates the need for server rewriting / page splitting, which has a
>> lot of gnarly edge conditions. Handling this at the transport layer would
>> make it much, much simpler and more powerful.
>> (Yes, we could lower the initial window for all streams, but that's
>> counter productive in majority of cases... we'd just end up sending a lot
>> more WINDOW_UPDATE frames for non-prefetch request.)
>> Further, the ability to set a custom window size also allows us to adjust
>> this logic based on type of asset, prior knowledge of the site, or other
>> signals. For example, the other use case is progressive rendering of images
>> - i.e. using flow control to fetch image layers and having control over
>> where and when to stop. Concretely, we could fetch first X KB, which may
>> provide a reasonable low-res preview of the asset, and then continue
>> fetching subsequent layers until some condition is met (end of file, or max
>> resolution of device is reached -- if you're a 2x device, don't fetch the
>> 3x layers). I'm intentionally skipping over the image container
>> discussions here, since that's a separate conversation.. But I'll note that
>> many sites are already trying to provide this sort of experience, except
>> through rather poor implementation: inline low-res asset, render that, then
>> initiate a separate XHR to fetch image and replace with high-res version.
>> Needless to say, we can do much better, and there is strong interest in
>> providing this sort of functionality natively...
>> --
>> In short, there are interesting cases where the initiator of the stream
>> may want to control the initial window size: to decrease it, and perhaps
>> even to increase it in some cases. There are multiple ways to achieve this,
>> but one plausible strategy would be to allow an optional SETTINGS_INITIAL_WINDOW_SIZE
>> payload in the headers frame, not unlike the optional priority field --
>> minimal overhead, no races between initiating the request and
>> Thoughts?
>> Ilya
>> [1]
>> [2]
>> [3]
>> [4]

Received on Thursday, 10 October 2013 06:27:49 UTC