Save-Data aware HTTP/2 server push

Server-initiated push is a new feature in HTTP/2 that can greatly improve page load performance by pushing critical resources to the client without requiring the client to request the download first. The only caveat by preemptively pushing out resources is that the server won’t be aware of the client’s local cache. This not only wastes bandwidth for both visitors and websites, but can potentially cost visitors with high data charges dearly.

The decision whether to push a resource or not is normally taken without the user having a say. Web developers must choose on their visitors behalf between potential page load performance gains and potentially running up their data usage and running against their data caps. The new Save-Data request header, which I’ve already introduced in greater detail already, let users have a say in the performance versus bandwidth-usage decision making process.

A website that have implemented HTTP/2 server push can become cache-aware by setting cookies on their visitors’ devices. These cookies can be implemented in a way to act like a toggles to turn off repeated server push in future requests. However, this requires added complexity at the edge to map cache-token cookies and resources the server would normally push to all clients. For smaller resources, it may not be worth the extra time and investment to avoid pushing already served-and-cached resources.

The additional data spent by repeated server pushes is a worthwhile performance compromise for many people in parts of the world. If you pay a lot for data usage, you may prefer websites to work in the more traditional dumber fashion where the client has greater control over what resources they fetch.

Some users will prefer to keep their bandwidth usage as low as possible. It’s entirely up to web developers to strike a balance between potential performance gains and potentially wasted bandwidth.

People who want to save bandwidth can configure their clients to send a Save-Data request header. This is added automatically to all requests when using the Data Saver feature in Google Chrome or Android, or Turbo mode in Opera or Yandex.browser. The header is a clear signal from the user that they want the server to do what it can to keep the bandwidth usage low.

If you don’t want to use a third-party compression proxy like Google Data Saver or Opera Turbo, you can also install my Save-Data: on extension for Firefox or Google Chrome. All the extension does is to include the Data-Saver header with every request.

In a situation where a client sends this header, a HTTP/2 server push can be disabled entirely — or scaled back to include only a few small resources. Websites shouldn’t push large resources at any time, but may push smaller things like only the smallest critical stylesheets and scripts. For some types of resources, like redirects, it makes sense to enable server pushed redirects whenever possible.

The two examples below show how you can configure this behavior by removing any Link: rel=preload response headers in response to any incoming Save-Data request headers.

if (req.http.Save-Data == "on") {
  unset resp.http.Link;
}

The above configuration example is for the Varnish Cache, and the below example is for the Apache HTTP Server:

SetEnvIfNoCase ^Save-Data$ "on" data_saver="on"
Header unset Link env=data_saver

Do remember to also add a Vary response header to indicate that a resource varies based on the presence of the Save-Data request header. This helps intermediary caches and proxies, whether it be your backend or on the visitor’s side, do the right thing.

Vary: Save-Data

Please make sure to carefully test your implementation thoroughly. Substandard web servers with weak HTTP caching implementations (like Nginx) may have issues performing cache negotiation when resources vary other than their Accept-Encoding. You should always test and verify that you’re not serving the wrong variant.

I hope I’ll find that your HTTP/2 cache-pushing websites support the Save-Data header whenever I next visit it from an expensive mobile plan! Maybe you’ll even find the time to do some more Save-Data optimizations while your at it.

Update (): Chrome has announced plans to remove support for server push.