Subscribe to receive notifications of new posts:

Subscription confirmed. Thank you for subscribing!

HTTP/2 Server Push with multiple assets per Link header


In April we announced that we had added experimental support for HTTP/2 Server Push to all CloudFlare web sites. We did this so that our customers could iterate on this new functionality.

CC BY 2.0 image by

Our implementation of Server Push made use of the HTTP Link header as detailed in W3C Preload Working Draft.

We also showed how to make Server Push work from within PHP code and many people started testing and using this feature.

However, there was a serious restriction in our initial version: it was not possible to specify more than one asset per Link header for Server Push and many CMS and web development platforms would not allow multiple Link headers.

We have now addressed that problem and it is possible to request that multiple assets be pushed in a single Link header. This change is live and was used to push assets in this blog post to your browser if your browser supports HTTP/2.

When CloudFlare reads a Link header sent by an origin web server it will remove assets that it pushes from the Link header passed on to the web browser. That made it a little difficult to debug problems with Link and Server Push so we have added a header called Cf-H2-Pushed which contains the assets that were pushed.

For example, browsing to this recent blog post results in the origin web server sending the following headers:

Cache-Control: public, max-age=0
Content-Encoding: gzip
Content-Length: 33640
Content-Type: text/html; charset=utf-8
Date: Wed, 29 Jun 2016 16:09:37 GMT
Expires: Wed, 29 Jun 2016 16:10:07 GMT
Link: </assets/css/screen.css?v=5fc240c512>; rel=preload; as=style,<//>; rel=preload; as=script,</content/images/2016/06/Timeouts-001.png>; rel=preload; as=image,</content/images/2016/06/Timeouts-002.png>; rel=preload; as=image,<//>; rel=preload; as=script,<>; rel=preload; as=script,</assets/js/jquery.fitvids.js?v=5fc240c512>; rel=preload; as=script
Vary: Accept-Encoding
X-Ghost-Cache-Status:From Cache
X-Powered-By: Express 

CloudFlare decides to HTTP/2 Server Push the assets /assets/css/screen.css?v=5fc240c512, /content/images/2016/06/Timeouts-001.png, /content/images/2016/06/Timeouts-002.png and /assets/js/jquery.fitvids.js?v=5fc240c512. As the response passes through CloudFlare those assets are removed from the Link header, pushed and added to the Cf-H2-Pushed header:

cache-control:public, max-age=30
content-type:text/html; charset=utf-8
date:Wed, 29 Jun 2016 16:09:37 GMT
expires:Wed, 29 Jun 2016 16:10:07 GMT
link:<//>; rel=preload; as=script,<//>; rel=preload; as=script,<>; rel=preload; as=script
status:200 OK
x-ghost-cache-status:From Cache

In Google Chrome Canary's Developer view the pushed assets can be clearly seen.


Please let us know how you use Server Push. We're particularly interested in experiences with pushing different types of resources (images vs. styles vs. scripts) and working out the optimal number of items to push (we currently allow up to 50 resources per page).

We protect entire corporate networks, help customers build Internet-scale applications efficiently, accelerate any website or Internet application, ward off DDoS attacks, keep hackers at bay, and can help you on your journey to Zero Trust.

Visit from any device to get started with our free app that makes your Internet faster and safer.

To learn more about our mission to help build a better Internet, start here. If you're looking for a new career direction, check out our open positions.

HTTP2 php Reliability Programming Server Push

Follow on Twitter

John Graham-Cumming |@jgrahamc
Cloudflare |Cloudflare

Related Posts

September 23, 2017 1:01AM

A New API Binding: cloudflare-php

Back in May last year, one of my colleagues blogged about the introduction of our Python binding for the Cloudflare API and drew reference to our other bindings in Go and Node. Today we are complimenting this range by introducing a new official binding, this time in PHP....

php API Programming Developers Python