Brotli vs Gzip Compression. How we improved our latency by 37%

In today’s world, customer experience is the most reliable and efficient strategy one can develop in order to increase the engagement, thus business. In this post we’ll focus on giving the customers something to experience as fast as possible i.e fast page load.

According to a Google study, 40% of people abandon a website that takes more than 3 seconds to load and a 1-second delay in page response can result in a 7% reduction in conversions. Yes, every second matters! And we saved around 2.5 seconds (90th percentile) and 1.2 seconds (50th percentile) by using Brotli compression over gzip compression for our Javascript and CSS files.

What the heck is Brotli?

Just like gzip, Brotli is also a compression algorithm. It is developed by Google and serves best for text compression. The reason being, it uses a dictionary of common keywords and phrases on both client and server side and thus gives a better compression ratio. It is supported by all major browsers :

Image Credit: caniuse.com

Does your browser support Brotli?
Browsers which support Brotli send ‘br’ along with ‘gzip’ in accept-encoding request header. If Brotli is enabled on your web server, you will get response in Brotli compressed format.

We can check the encoding in response header (Image Credit: Certsimple)

Gzip vs Brotli:

The advantage for Brotli over gzip is that it makes use of a dictionary and thus it only needs to send keys instead of full keywords. According to certsimple,

  • Javascript files compressed with Brotli are 14% smaller than gzip.
  • HTML files are 21% smaller than gzip.
  • CSS files are 17% smaller than gzip.
Note: Images should not be compressed either by gzip or Brotli as they are already compressed and compressing them again will make their sizes larger.

Fewer bytes transferred not only leads to faster page load but also helps in reducing costs of Content Delivery Network (CDN). Now that we know all these benefits, let’s see how to enable Brotli…

Embracing the Brotli side:

There were two ways by which we can deliver Brotli compressed assets:

  • Enabling Brotli on our web-server
  • Enabling Brotli on CDNs

We chose to go ahead with serving Brotli from our web servers and installed it on nginx. Google has provided a module for it which needs nginx to be installed from source. Once installed, the following settings need to be put in nginx conf file:

brotli on;
brotli_static on;        # for static compression, explained later
brotli_comp_level 11;    # this setting can vary from 1-11
brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;

After this, all content types which are mentioned in brotli_types setting will be brotli compressed. Easy, wasn’t it!

Note: We have to keep gzip settings on nginx intact as clients who doesn’t support br should get gzip compressed files. Although nginx gives precedence to br if both are supported.

Here, our web server will send br compressed assets, then CDN will just cache it and pass on to the browser.

Another way to enable Brotli is via CDN. By this way you don’t have to write any code or install anything in your infra, but this will be a paid service. We went for the ‘Brotli from Origin’ approach (former), as it is more cost efficient and engineering is what we like to do.

Dynamic vs Static Compression:

Dynamic compression means compressing files on the fly whereas static means to compress files once and then serve every time from cache. We used static compression for our Javascript and CSS files, as those will not change (until a new build is deployed). All these files are then cached on CDN and get served from there itself.

We talked about a setting ‘brotli_comp_level’ above and promised to explain it later, so here it is. It indicates the compression ratio and ranges between 1 to 11. Higher the ratio, higher the time it will take to compress it. So we used the value 11 for our static assets. For Dynamic assets like API responses , we should use smaller values - a high compression time can backfire, and put all our efforts to improve latency to turmoil.

Results :

26% Reduction in CSS file-sizes
17% Reduction in Javascript file-sizes
Overall Results

What’s next :

  • Currently, we are only using Brotli for Javascript and CSS files, in future we will try to use it for HTML document and API calls. We will have to tune the compression level setting in such a way so that compression time and ratio combined is lower than gzip.

Useful Resources:

Let me know if this was worth your time by throwing claps.


Do read my other blog on how to Find or Delete multiple keys by pattern in redis without blocking it in production environment: