> ## Content Index
> Fetch the complete content index at: https://www.ctrl.blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# Save-Data aware HTTP/2 server push
- URL: https://www.ctrl.blog/entry/http2-save-data-push/
- Published: 2017-10-03T07:40:00.000Z
- Updated: 2026-08-23T22:11:44.000Z
- Description: Learn how to set up HTTP Save-Data request-hint aware HTTP/2 server push with Apache HTTPD and Nginx web servers.
- Author: Daniel Aleksandersen
- Tags: Hypertext, WebPerf

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](https://www.ctrl.blog/entry/http-save-data/) 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](https://addons.mozilla.org/en-US/firefox/addon/save-data/?ref=ctrl.blog) or [Google Chrome](https://chrome.google.com/webstore/detail/save-data-on/nholpkfnmjbinlhcfihkhiehdaohlibg?ref=ctrl.blog). 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](https://www.ctrl.blog/entry/http2-push-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.

```javascript
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:

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

Do remember to also add a [Vary response header](https://www.ctrl.blog/entry/http-vary-explained/) 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](https://www.ctrl.blog/entry/http-save-data/) while your at it.

**Update** (2020-11-30): Chrome has announced plans to [remove support for server push](https://www.ctrl.blog/entry/http2-push-chromium-deprecation/).

#### Sources

- [Preload](https://www.w3.org/TR/preload/?ref=ctrl.blog), 2017-08-30, Specification Working Draft, World Wide Web Consortium (W3C)
- [HTTP Client Hints](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-client-hints-04?ref=ctrl.blog), 2017-04-18, HTTP Working Group, Internet Engineering Task Force
- [Data Saver](https://web.archive.org/web/20171114184320/https://developer.chrome.com/multidevice/data-compression), Chrome for a Multi-Device World, Google Developer
- [RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2)](https://www.rfc-editor.org/rfc/rfc7540.html?ref=ctrl.blog), 2015-05, Internet Engineering Task Force