site logoTune The Web
I've written a book! - click here to view or buy "HTTP/2 in Action" from Manning. Use code 39pollard to get 39% off!

Brotli Compression

This page was originally created on and last edited on .

Introduction

Most websites (if configured correctly!) use gzip to compress text files before they are sent across the internet. This makes the files smaller, and then the web browser will automatically unzip them. The lose in the zipping and unzipping time is more than made up for in performance gains - at least for text files. This is because text files are pretty inefficient in terms of space used (they are meant for humans more and for machines).

Brotli is a new compression format launched by Google in September 2015 which claims to save 20%-26% over their previous gzip compatible implementation, for similar speeds. Now, while that sounds impressive, do remember that most of the bandwidth hogs on web pages are media, which should not be gzipped as they are already compressed, so if you have gzip enabled fro text files, then there are small gains to be got from shifting to Brotli, but don't expect massive gains unless you are a text only site. Still every little counts and, if it's easy enough to install, then why not.

How to set it up

Apache added Brotli support to 2.4.26, but it does require the Brotli library and some compile options. So if you are already installing Apache from source then that's not a problem, but if not then you should read the warnings I give on the HTTP/2 page about considerations when compiling from source. With that caveat aside, to enable Brotli on Apache do the following:

#You may need to install some dependencies if not already installed on your machine. #For Centos/RHEL 7 the following should do this for you: sudo yum install wget sudo yum install perl sudo yum install gcc sudo yum install pcre-devel sudo yum install cmake.x86_64 cd ~ mkdir sources cd sources #Download and install brotli git clone https://github.com/google/brotli.git cd brotli/ git checkout v1.0 mkdir out && cd out ../configure-cmake make make test sudo make install #Download and install the latest Apache (needs to be 2.4.26 or above) #For example: #wget http://mirrors.whoishostingthis.com/apache/httpd/httpd-2.4.33.tar.gz #wget https://www.apache.org/dist/httpd/httpd-2.4.33.tar.gz.asc #Verify the package after download (not covered here but can be done with: gpg --verify httpd-2.4.33.tar.gz.asc) tar -zxvf httpd-2.4.33.tar.gz cd httpd-2.4.33 ./configure --with-pcre=/usr/bin/pcre-config --enable-ssl --enable-so --enable-brotli --with-brotli=/usr/local/brotli make sudo make install

Next up you need to enable it in your Apache config. The configuration is very similar to Gzip configuration (Called Deflate in Apache for historical reasons), so config like this will do the job:

LoadModule deflate_module modules/mod_deflate.so LoadModule brotli_module modules/mod_brotli.so <IfModule mod_brotli.c> AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon BrotliFilterNote Input brotli_input_info BrotliFilterNote Output brotli_output_info BrotliFilterNote Ratio brotli_ratio_info LogFormat '"%r" %{brotli_output_info}n/%{brotli_input_info}n (%{brotli_ratio_info}n%%)' brotli CustomLog "|${APACHE_ROOT}/bin/rotatelogs ${APACHE_LOG_DIR}/brotli_log.%Y%m%d 86400" brotli #Don't compress content which is already compressed SetEnvIfNoCase Request_URI \ \.(gif|jpe?g|png|swf|woff|woff2) no-brotli dont-vary # Make sure proxies don't deliver the wrong content Header append Vary Accept-Encoding env=!dont-vary </IfModule> <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript application/json application/x-font-ttf application/vnd.ms-fontobject image/x-icon DeflateFilterNote Input input_info DeflateFilterNote Output output_info DeflateFilterNote Ratio ratio_info LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate CustomLog "|${APACHE_ROOT}/bin/rotatelogs ${APACHE_LOG_DIR}/deflate_log.%Y%m%d 86400" deflate #Don't compress content which is already compressed SetEnvIfNoCase Request_URI \ \.(gif|jpe?g|png|swf|woff|woff2) no-gzip dont-vary # Make sure proxies don't deliver the wrong content Header append Vary Accept-Encoding env=!dont-vary </IfModule>

Note that you need to specify the Brotli config first, or Apache will use gzip in preference to Brotli. And you should continue to configure gzip for older browsers that do not yet support Brotli.

After this restart your Apache and you should see a Content-Encoding of "br" on your text resources, instead of the usual "gzip":

Brotli Compression as shown in Chrome Developer Tools

You can try turning mod_brotli off and on again to see the improvements it makes. I noticed a good level of improvements on the text resources but, as hinted at above, the overall page load barely moved since most of this is made up of images which do not benefit from this. Still - every little helps!

Support

Support for Brotli is pretty good, with the Chrome, Firefox, Opera, Android and even Edge supporting it. Apple has just added it to Safari and iOS 11 so when they are launched then that will be pretty much all the main browsers. Internet Explorer of course won't support it, and annoyingly IE and Edge don't even show the Content-Encoding headers (gzip or br) in their developer tools, so it's actually quite difficult to see if this is being used or not. You can add a custom log format in Apache to see this on the server side (using "%{Content-Encoding}o"), which might be useful. My preferred LogFormat at the moment is shown below:

LogFormat "%h %l %u %t %{ms}T \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{SSL_PROTOCOL}x %{SSL_CIPHER}x %{Content-Encoding}o" combined

One important thing to note is that browsers will only support Brotli over HTTPS. This is because some older proxies don't handle new formats well, where as when behind HTTPS they can't see content so don't cause any problems, and is also part of a wider trend by the Internet community moving to HTTPS and only enabling New Features on HTTPS domains. The plus side, is this is a good way of checking your fall back to gzip - since nearly all browsers support Brotli now and IE doesn't show Content Encoding headers (another option is to disable Brotli support in Chrome using the chrome://flags/#enable-brotli screen:

No Brotli Compression over HTTP

While client side support is good, for Web Browsers at least, on the server side, support is less popular. Apache added support in 2.4.26, though it was available on non-production branches, or through downloading a separate module from GitHub. Nginx doesn't yet have Brotli support in it's production branch, though again you can download a separate module created by Google for this and IIS is similar with a separate download to add Brotli Support. Note these all require downloading the core Brotli code from GitHub in addition so they are not as fully built in as gzip. NodeJS hasn't added support natively yet, though there are various requests (for example to add Brotli to the Express framework for Node). Adding Brotli support to Java similarly, currently requires using 3rd party code.

The Downsides

Other than the hassle of setting it up, and the lack of support on the server side at present, there are no real downsides to using Brotli. It really is a set up and forget about it type option.

Summary

Brotli is a nice update over gzip and, whiel the performance gains are not massive, it only requires a one time set up and can then be forgotten about.

This page was originally created on and last edited on .

How useful was this page?
Loading interactions…