Implementation Notes on Server Push

Patrick McManus <> Tue, 14 May 2013 19:17 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 3F01A21F90D2 for <>; Tue, 14 May 2013 12:17:44 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -9.976
X-Spam-Status: No, score=-9.976 tagged_above=-999 required=5 tests=[BAYES_00=-2.599, FM_FORGED_GMAIL=0.622, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_HI=-8]
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id HeWkeNwl8fG9 for <>; Tue, 14 May 2013 12:17:35 -0700 (PDT)
Received: from ( []) by (Postfix) with ESMTP id A58A521F8EAC for <>; Tue, 14 May 2013 12:17:33 -0700 (PDT)
Received: from lists by with local (Exim 4.72) (envelope-from <>) id 1UcKhH-0000Xl-9A for; Tue, 14 May 2013 19:15:39 +0000
Resent-Date: Tue, 14 May 2013 19:15:39 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtp (Exim 4.72) (envelope-from <>) id 1UcKh5-0000Ws-1H for; Tue, 14 May 2013 19:15:27 +0000
Received: from ([]) by with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.72) (envelope-from <>) id 1UcKh3-0004aa-TF for; Tue, 14 May 2013 19:15:26 +0000
Received: by with SMTP id j6so1140273oag.18 for <>; Tue, 14 May 2013 12:14:59 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20120113; h=mime-version:x-received:sender:date:x-google-sender-auth:message-id :subject:from:to:content-type; bh=zO9uMTiyJylKKOsuzKsGUi4ww69CiOroMaP/4b/GuU8=; b=NOWZgUMbFEjoiG9YI6YwVIz528zTyButTkioPbIMWzbHZ9GH/4UNiZglnM8QlWpkrn tRpwBEW+4pCfVn9ffqZnNZ3ggH/v0VjOQiWEjdL/9AUeO3q8zN8QkFlnjzASotAv6vE6 r3Igqrlexa9Z8pBHrDzk8TorJnQ/O0SaD14AN3h28oPDxQy53SvgII068K5KgsPw2akj r5Q8WNWffb322UquRTPzZUC6qISHuvIzWI222n5hJCMuhHOR/RvUmNZaPuZZrknwBYvz aULwRy1gT1nufLB4mqiuDupLye8re9gqoHU+b8UyxhbTmNccIG5f7Z+ogUmau6ZlF1A4 6wtg==
MIME-Version: 1.0
X-Received: by with SMTP id fr10mr1118343obb.85.1368558899791; Tue, 14 May 2013 12:14:59 -0700 (PDT)
Received: by with HTTP; Tue, 14 May 2013 12:14:59 -0700 (PDT)
Date: Tue, 14 May 2013 15:14:59 -0400
X-Google-Sender-Auth: Qa7ylP6j85vM5F93qzQ21JI5GLM
Message-ID: <>
From: Patrick McManus <>
To: HTTP Working Group <>
Content-Type: multipart/alternative; boundary=089e0129526a138dee04dcb2732f
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-3.3
X-W3C-Hub-Spam-Report: AWL=-2.628, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001
X-W3C-Scan-Sig: 1UcKh3-0004aa-TF 9f18ceb221bba07e72c014469226e893
Subject: Implementation Notes on Server Push
Archived-At: <>
X-Mailing-List: <> archive/latest/17992
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

I'm wrapping up a Firefox implementation of spdy/3 server push and wanted
to provide some ietf level feedback because that mechanism is largely
intact in the current http2 work in progress draft.

   - 304's seem to be a common cause of wasted pushed streams. I would see
   servers respond with a 304 for index.html and still push 200 responses for
   a.css and b.js when in a non-push world that would have been either 1 or 3
   304's. Maybe we should have a rule that you can only push to an
   assoc-stream of 2xx ?
   - There is language in the spec that if the client resets a stream that
   it implicitly resets any associated streams too. That was complicated to
   implement and pretty much broke my stream state model internally - while
   researching it it appears that mod_spdy and chrome don't implement it at
   all. The spec has an editorial note about removing that feature and I favor
   that removal.
   - I found flow control for pushed streams immensely helpful. It lets the
   client bound how much data can be pushed before there is a local GET
   matched up with that. Relatedly, I changed my default SETTINGS window size
   from a ~infinite value to be a smaller push-apropos value and then
   pipelined a window update with each odd SYN_STREAM to make pulled streams
   ~infinite again while preserving the smaller limit for push and this worked
   fine with all existing servers to my pleasant surprise. That seems to mean
   at least the spdy/3 windowing mechanism is simple enough for people to get
   - As with other parts of the spec, I was faced in some implementations
   with some very large data frames (90+KB) from servers when testing. Such
   frames are impervious to CANCEL or any mechanism we might use to change
   priorities driven by the client :(..  HTTP2 is doing the right thing by
   creating a smallish max frame size.

Obviously this is implementation experience with testing and isn't real
operational experience yet.. that will come.