Update on Jan 15 2018

Note that Apache now comes with Brotli built-in. I did not remove this post for historical reasons but please do not download the compiled modules at the end of this post. The configuration directives have changed too. Please refer to the official documentation.

Old post:

Google's Brotli compression algorithm is currently available in Chrome and Firefox, and it is supposed to give about 25% more compression without additional CPU or memory use. For Nginx, there is a implementation from Google themselves. My favorite web server, Apache, still lacks Brotli compression support in its stable branch.

There is, however, a third party Apache module kjdev/apache-mod-brotli that I could get working, and so far the results are promising.

Below is a comparison of file sizes in uncompressed, gzipped, and Brotli-compressed formats:

Compared to the gzip results, all the text-based assets had their size reduced between 8.84% - 23.52%, and average of about 10% for that page! The difference is not dramatic at first, but considering over 50% of the browsers support Brotli, and the CPU/Memory difference is about the same, it is worth implementing Brotli support.





Prerequisites

I'm not sure if there is a technical reason behind this, but all the browsers I tested with require HTTPS in order to enable Brotli support. I have written a small post about more reasons to switch to HTTPS as well. Other than that, you will need to build the Apache module yourself (I have mine available to download at the bottom of this page).

Apache installed.

HTTPS enabled.

Access to your Apache installation (so no shared hosts)

Brotli binary installed

To install the Brotli binary, simply run apt-get install brotli (or equivalent package manager command).





Build the module

I have the compiled .so file at the bottom of this post. However, I strongly encourage you to compile it yourself. Shouldn't take more than a few minutes. Note that these instructions are for Debian/Ubuntu based systems. CentOS/RHEL folks should be able to get this working as well; just swap the package manager commands with yum or whatever package manager you use.

FIrst, install the Apache2-dev package.

apt-get install apache2-dev

This will install a bunch of tools that you need to compile the module.

git clone --depth=1 --recursive https://github.com/kjdev/apache-mod-brotli.git

cd apache-mod-brotli

./autogen.sh

./configure

make

This will clone the module from Github, and build the module. The .so file will be available inside the .libs folder. Now, lets put the module where other Apache modules are installed:

install -D .libs/mod_brotli.so /usr/lib/apache2/modules/mod_brotli.so -m 644





Install the module

Now with the module built, and moved among the other modules, it is time to enable the module!

Recent Apache versions come with the handy a2enmod program to enable modules (and a2dismod to disable). In order for it to detect our new module, we need to create a .load file with the module load information.

cd /etc/apache2/mods-available

echo "LoadModule brotli_module /usr/lib/apache2/modules/mod_brotli.so" > brotli.load

This will create and add the module path to a brotli.load file. Next, we need to create a configuration file for Brotli to work.

nano brotli.conf

This will open up nano with the new file brotli.conf . As a base configuration, put the following:

<IfModule brotli_module>

# Compression

## BrotliCompressionLevel: 0-11 (default: 11)

BrotliCompressionLevel 10 ## BrotliWindowSize: 10-24 (default: 22)

BrotliWindowSize 22 # Logging

# Filter note

BrotliFilterNote Input brotli_in

BrotliFilterNote Output brotli_out

BrotliFilterNote Ratio brotli_ratio #LogFormat '"%r" %{brotli_out}n/%{brotli_in}n (%{brotli_ratio}n)' brotli

#CustomLog ${APACHE_LOG_DIR}/brotli_access.log brotli # Output filter

AddOutputFilterByType BROTLI text/html text/plain text/css text/xml

AddOutputFilterByType BROTLI text/css

AddOutputFilterByType BROTLI application/x-javascript application/javascript

AddOutputFilterByType BROTLI application/rss+xml

AddOutputFilterByType BROTLI application/xml

AddOutputFilterByType BROTLI application/json # Global output filer if necessary.

# SetOutputFilter BROTLI

# SetEnvIfNoCase Request_URI \.txt$ no-br </IfModule>

You can configure the Brotli compression level between 1 and 11. The module developers recommend setting is 10. There is a paper on the compression level and their performance compared if you would like to change this value.

Optionally, you can also log the Brotli-served Logs with their information to a custom log file. Uncomment as necessary.

Under Output filters, we enable Brotli compression for a bunch of common content types.Again, modify them as necessary. Do note that you will not gain any improvements on file formats that are already compressed for obvious reasons. Most of the content types in the configuration above are the same types used with mod_deflate (gzip). I added application/json of my own.





Enable the module

a2enmod brotli

service apache2 restart

You should have Brotli running with Apache. Inspect the browser request headers that have Accept-encoding: ... br , and make sure that the response contains Content-encoding: br header.











Compiled module

For those who don't want to build the module yourself, you can download the module and configuration files below. It was built for my Ubuntu 16.10 VPS running Apache 2.4.23. YMMV.