Re: Experiences with HTTP/2 server push

Tom Bergan <> Mon, 08 August 2016 19:41 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id B089F12B02C for <>; Mon, 8 Aug 2016 12:41:17 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -8.267
X-Spam-Status: No, score=-8.267 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-1.247, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (1024-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id am7Z0RTSYfee for <>; Mon, 8 Aug 2016 12:41:12 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id F1CC612B02B for <>; Mon, 8 Aug 2016 12:41:11 -0700 (PDT)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1bWqMP-0000UF-UE for; Mon, 08 Aug 2016 19:37:17 +0000
Resent-Date: Mon, 08 Aug 2016 19:37:17 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1bWqMJ-0000T3-Jg for; Mon, 08 Aug 2016 19:37:11 +0000
Received: from ([]) by with esmtps (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1bWqME-0004Zc-Bd for; Mon, 08 Aug 2016 19:37:10 +0000
Received: by with SMTP id f6so91902772ith.0 for <>; Mon, 08 Aug 2016 12:36:45 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=ZxHrHeI7DpXvm4uIAX4WnuFmy/XjV1/Vk4WPGt4P21k=; b=hPFYELcr/Dt8SUQJgdgl60sevlvHPtGMlUt0RvAnHui3wSe/7lqqPiDhqXttYOGQiC sQY3hK/mU74HZeU0uJPLaHdySQTvVjhnjj4ygIOSIsSvmJEouhCNl8sxg4TiYFWfQBAy 60dI6zinxf0Jf98mbxygkFZFhXKRHAbje+uP8=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=ZxHrHeI7DpXvm4uIAX4WnuFmy/XjV1/Vk4WPGt4P21k=; b=fTtX8LaxcIcYN1iyAofIC8vWdEhyPEl/lgYjv7W7TyDc4R5c0dsULvYKznz7GIwQO2 XOwNn7mZ93GSrGpuu5fxz0hr8WPjLeuY0hG9iFl0FjPznlePX+QMFvK/De4ahv51VIhz n16ILGxy9FzmqLrYENU5vZ2JjH0D6q//e0flwVw53H3zxA8hZU43Dw4mvgLLVsOdufHU ZnWm+Ue8rHikDpcVbtKwZ+47GcydwWsgc+aeWfazo3P0mPO6anzj31LKL9lWTxuKkzms qQkV+7fFVtRnVHNyz9Lj86lr95I9+sYnRQGoLZSBJ3i/NgR2L4xCHCi5PWd1kk07Nyx4 zrDA==
X-Gm-Message-State: AEkoouub69MVds9cAjVSRjYJgMDvmb2T1tVAl0dHKBIrkSpvbZmM5byGEFwiz88IJFM14GAd
X-Received: by with SMTP id 134mr19087908itf.70.1470681612945; Mon, 08 Aug 2016 11:40:12 -0700 (PDT)
Received: from ( []) by with ESMTPSA id f9sm14901773ioi.2.2016. for <> (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 08 Aug 2016 11:40:12 -0700 (PDT)
Received: by with SMTP id f6so90467435ith.0 for <>; Mon, 08 Aug 2016 11:40:12 -0700 (PDT)
X-Received: by with SMTP id u134mr20708766ita.38.1470681611645; Mon, 08 Aug 2016 11:40:11 -0700 (PDT)
MIME-Version: 1.0
Received: by with HTTP; Mon, 8 Aug 2016 11:40:10 -0700 (PDT)
In-Reply-To: <>
References: <> <> <> <>
From: Tom Bergan <>
Date: Mon, 08 Aug 2016 11:40:10 -0700
X-Gmail-Original-Message-ID: <>
Message-ID: <>
To: HTTP Working Group <>
Cc: Stefan Eissing <>,, Martin Thomson <>
Content-Type: multipart/alternative; boundary="001a1135018c0ad01e053993bfb7"
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-4.7
X-W3C-Hub-Spam-Report: BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001, W3C_AA=-1, W3C_WL=-1
X-W3C-Scan-Sig: 1bWqME-0004Zc-Bd d121639591cc485b3006cfb12feb3453
Subject: Re: Experiences with HTTP/2 server push
Archived-At: <>
X-Mailing-List: <> archive/latest/32226
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

Thanks all for the feedback.

On Fri, Aug 5, 2016 at 12:07 PM, Alcides Viamontes E <> wrote:
> If browser and server are a bit far apart re-prioritization may arrive a
> bit too late to the server to be effective. Our solution for both  the race
> conditions and the RTT problem  is having our server learn the priorities
> and dependencies, build a delivery plan once and use it many times. In that
> sense, priorities and dependencies on the HTTP/2 spec as it is today is
> good enough for us. And the implementation complexity is about the same as
> implementing on-the-flight re-prioritization.

If you can come up with a complete delivery plan on the server, that is
definitely ideal. There is some academic work that tries to do this (see
Klotski: I also liked your
"Coordinated Image Loading" article as an example of why server-defined
priorities can be a good idea. I am curious though -- how do you deal with
cases where the page is heavily dynamic and some of the important content
may be fetched by XHRs? Do you expect that the full dependency information
is available a priori, before the main response is served to the client?

> > Our team has been experimenting with H2 server push at Google for a few
>>> > months. We found that it takes a surprising amount of careful
>>> reasoning to
>>> > understand why your web page is or isn't seeing better performance
>>> with H2
>>> > push.
> Oh, but it is a lot of fun :-)

It is for us too :-), but I imagine many devs would find it frustrating.
Hence our attempt to try to distill our experiences into a "best practices"

> In our experience as well the biggest performance killer of HTTP/2 Push is
> TCP slow start and the fact that push promises are bulky. Send many of them
> and an ACK round-trip will be needed.

Interesting point about needing ACK round-trips just to send the push
promises. We hadn't run across that problem specifically. Is this because
you're sending many push promises? Is there some reason why hpack cannot
compress a sequence of push promises?

If you've released any data about HTTP/2 Push performance in ShimmerCat,
I'd be interested to read it. I did notice one article on your site,
although that only dealt with one page with a fixed network connection:

On Sun, Aug 7, 2016 at 7:02 PM, Martin Thomson <>
> I think that you still misunderstand.  The priority tree is the
> client's data.  The server cannot mutate it because it doesn't own it.
> As you say, if the server makes changes, the state is ruined.

I'm not sure what I misunderstand? It sounds like we're saying the same
thing: the server should not mutate the priority tree if it wants to
continue using priority information from the client. (The counter-point is
Alcides' example, where the server uses its own delivery plan and ignores
the client's PRIORITY frames entirely.)

Note that no client I'm aware of will do anything with the server's
> PRIORITY frames, let alone adjust its own priority tree.

To be clear:

* As I mentioned above, I'm not aware of any server that tries to send
PRIORITY frames to the client. That discussion was intended to dissuade a
naive server from attempting to do so. AFAIK, servers that do mutate the
priority tree just mutate the server's in-memory representation of the
tree, e.g., I believe this is what Apache does with h2_session_set_prio,
which is applied to pushed streams (more info here

* Apache is technically not doing anything illegal. Servers are free to do
anything they want with priority information. (From Section 5.3: "priority
for a stream is input to a prioritization process. It does not guarantee
any particular processing or transmission order for the stream relative to
any other stream ... priority is therefore only a suggestion".) The problem
comes when servers want to mix their own priorities (e.g., for pushes) with
the client's priorities. It is tempting to do this by mutating a single
data structure. RFC 7540 doesn't discuss this temptation at all, which is
why we discussed it in our document.