Search

Compression

Compression

In an attempt to reduce the size of the response payload over the wire, various compression algorithms are used to compress the response body.

The most popular compression algorithm by far is gzip. HTTP has the mechanisms in place to perform content negotiation, and to request either the plain-text or the compressed version.

Content negotiation

In terms of content negotiation, the browser can advertise its content encoding capabilities by issuing an Accept-Encoding header containing the compression/encoding algorithms it supports.

Here’s what my browser advertises:

Accept-Encoding: gzip, deflate, br 

Basically, my browser supports gzip compression, deflate compression, and br compression. br is short for Brotli.

A server can choose one of the supported compression algorithms and return the algorithm it used for compression in the form of a Content-Encoding header.

Because gzip is the most popular web compression algorithm, web servers are likely to return the following response header:

Content-Encoding: gzip

Gzip compression in Varnish

Varnish natively supports gzip compression and encourages servers to send compressed responses to Varnish.

It does so by modifying the Accept-Encoding header to Accept-Encoding: gzip for every miss, regardless of the Accept-Encoding value that the client may have set.

Responses will be stored in cache in a compressed format. If it turns out that the client doesn’t support gzip, Varnish will decompress the response on-the-fly.

Because gunzip is very fast, it is more efficient to decompress on-the-fly than to store two versions of the object in cache.

When a client doesn’t support gzip, the plain-text version is returned, the Content-Encoding: gzip header is stripped off, and Etags get weakened.

When a gzip’ed object is stored in cache, a Vary: Accept-Encoding header will be returned to the client. Any attempt by the origin to issue a Vary: Accept-Encoding will be ignored because only the compressed version is kept.

If the origin doesn’t respond with a compressed response, Varnish will trust that it’s because the compression wasn’t worth it. This is the case for images, video and other binary resources. In such cases, the object is stored as-is, and user requests for compression will be ignored. The next section explains how to override this.

To explicitly disable gzip support in Varnish, the http_gzip_support runtime parameter can be disabled.

Gzip and VCL

Even though Varnish handles gzip compression behind the scenes, the VCL programming language still allows you to override the default behavior.

Imagine that your origin server doesn’t support gzip, but you still want to serve compressed content. In that case you can use the following VCL snippet:

sub vcl_backend_response {
    if (beresp.http.content-type ~ "text") {
        set beresp.do_gzip = true;
    }
}

As you can see, there is an if-condition in there to ensure that only plain-text content gets compressed. Binary content, such as JPEG images, shouldn’t be compressed.

You can also decompress gzip’ed content in VCL by setting set beresp.do_gunzip = true;. You can even check whether or not the client supports gzip through the req.can_gzip variable, which returns a boolean.

Brotli compression in Varnish

As of version 6.0.6r10 Brotli compression is supported in Varnish Enterprise. It is not available by default but requires vmod_brotli to be initialized.

The module can handle brotli-compressed responses from the origin, but it can also turn gzip-compressed data into Brotli.

Here’s a VCL example that will store gzip-compressed or plain-text objects into brotli-compressed objects:

vcl 4.1;

import brotli;

sub vcl_init {
  brotli.init(BOTH, transcode = true);
}

sub vcl_backend_response {
  if (beresp.http.content-encoding ~ "gzip" ||
      beresp.http.content-type ~ "text") {
    brotli.compress();
  }
}

By initializing vmod_brotli with BOTH as the encoding value, it can normalize the Accept-Encoding request header and support plain-text encoding, gzip encoding and Brotli encoding.

By setting the transcode argument to true, the module will decompress objects when the client doesn’t support Brotli, or transcode the object to gzip when the client only supports gzip.


®Varnish Software, Wallingatan 12, 111 60 Stockholm, Organization nr. 556805-6203