Subscribe to receive notifications of new posts:

HTTP/2 Server Push with multiple assets per Link header


3 min read

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.
HTTP2phpReliabilityProgrammingServer Push

Follow on X


Related posts