Chrome recently pushed out support for Brotli, in this post I will cover what this means to you.

In late May 2016 Chrome pushed out Chrome 51, unlike many releases of Chrome which are complete non-events, this release has an enormous impact. Google turned on Brotli support – and they promptly backported it into Chrome 50.

Firefox added support for Brotli in September 2015. They even blogged about it. 8 months later, thanks to Google, Brotli went from a compression format supported in less than 10% of global browsers to nearly 50% global adoption!

Brotli is HTTPS only

If you visit a site over HTTP your browser will not accept the br encoding. The reasoning for this is documented at the end of the chromium issue.


I have a question. What does intermediates refer to in the reason to restrict this feature to HTTPS only? Caches? If so, this may or may not be solved by adding no-transform to Cache-Control when you send Content-Encoding: br. I don't know.

I think that restricting to HTTPS is regrettable, as what you save with brotli you lose double by not having caching.


Intermediaries (or "middle boxes") refers to companies/infra/software meddling with the data transfer between you (the user) and the webserver.

One example from SDCH that was mentioned to me (the name of the company is not relevant to the discussion so I'm hiding it):

"The most extreme case of middle box was Company AcmeTelecom (fictitious name but true story), that tried to make things better when faced with unknown content encodings, by doing the following things:

a) Remove the unrecognized content encoding
b) Pass the (already compressed!) content through another gzip encoding pass
c) Claim that the content was merely encoded as gzip"

Lack of Brotli support over unencrypted HTTP is no mistake. The world is full of terribly non-compliant HTTP proxies:

Brotli is yet another reason for you to push for that HTTP/2 change you have been holding out on.

Brotli: The New Pied Piper?

When I first heard of Brotli, there were a lot of stats being published about how much better the compression is. The Next Web said it is 26% better. and Akamai blogged about its huge potential. I was thinking to myself… did we just uncover a real world pied piper?

In my measurements, the best case compression for Brotli really does blow away the competition:

(percentages are expressed as savings compared to gzip -9)

  • Even at level 5, Brotli is better than gzip -9
  • Worst case savings is 9.29% (for jQuery)
  • Best case savings is 29% (for our Discourse application js)
  • The larger the file, the better Brotli fares.
  • You can get a free 3-4% savings by using zopfli which is compatible with gzip decompression.

Comparing Brotli compression levels

Brotli, like other compression formats, offers a choice of compression levels, from 1 all the way to 11. Level 5 is where Brotli starts using context modelling, one of the more advanced features of the format.

Compressing Brotli at the highest setting is so slow gzip -9 is practically invisible from the graph!

  • Brotli at level 11 is not feasible for dynamic content
  • Brotli at level 5 is competitive with gzip and produces files that are even smaller than gzip -9
  • Zopfli is really slow, for large files it can take 4× the time of Brotli 11.

Brotli is not easy to adopt today

Another complication with Brotli is that it is missing-in-action.

Ubuntu 16.04 is the first Ubuntu distro with apt-get install brotli, if you want to play around on earlier distros you have to find a third party apt repo or compile it yourself.

NGINX has a Brotli extension, this is not distributed with the official NGINX package, forcing you to compile NGINX by yourself if you want brotli today.

sidenote: nginx -VV makes it significantly easier to self-compile NGINX without getting into a big mess.

Apache only recently got a Brotli extension

When it comes to the various asset pipelines out there, none of them support pre-compressing Brotli assets, so you have to bolt it in yourself.

Even with all these rather big hurdles you can have it today, and it does work!

Brotli decompression is fast

I did not include any graphs or stats for gzip and brotli decompression, they are simply so fast that I would need to build a rather elaborate test harness to get an accurate measure of the difference. It is simply so fast that it does not really matter. I found that the IO of writing the file is the bottleneck not the decompression.

CDN support for Brotli is uneven

Of the 4 CDNs I checked:

Fastly and MaxCDN had stripped out accept encoding for Brotli, falling back to gzip, CDN77 appears to be letting Brotli through. KeyCDN do not allow Brotli through (thouge they do provide you with a tool to check if your current CDN is allowing Brotli).

Fastly have a documented workaround, but support is not built in.

This uneven support is understandable. CDNs usually normalize the Accept-Encoding header. This happens cause there is a huge matrix of Accept-Encoding in the wild, if this is not normalized the same gzipped resource can be stored 44 times.

If a CDN allows brotli through it can quite easily double all the requests to your website for the origin resource. It has to check if you have both Brotli and gzip for every asset.

Considering that the vast amount of resources you are serving are probably not Brotli compressed, this can become very wasteful, especially if the first request to the asset comes from a browser that does not accept the br encoding like Safari or IE.

Ideally, CDNs should provide you with a way to whitelist some (or all) assets to opt out of Accept Encoding normalization.

Brotli is about to become an RFC

The magic date, May 25, 2016, was not randomly picked by Google for enabling Brotli in Chrome. It was the date IANA finally stamped the ietf draft with RFC Ed Queue. That is the final state the document enters prior to becoming an RFC and getting an RFC number. The approval announcement is already out.

The draft's authors submitted it to the Independent Stream in April 2014. It took the ISE rather a long time to find suitable reviewers for a new compression technique, but, it finally got a brief review from Ulrich Speidel(U Auckland, a coding theory researcher), and a more thorough review from Jean-Loup Gailly (the author of gzip). The authors made changes based on those reviews, and it is now ready for publication.

Google did the right thing in not rushing Brotli to the public, it is excellent that Jean-loup Gailly and Mark Adler the original authors of the gzip format had a chance to properly review the draft.

What can we do?

Proxy and web server vendors should make it easier to experiment with Brotli

I would like to see NGINX, Apache, HAProxy etc. make it easier for people to experiment with Brotli. For NGINX this means shipping with Brotli support in an optional official extension.

The biggest challenge ahead is figuring out a smart heuristic for figuring out which compression level to use balancing compression with CPU cost and current load on dynamic content. This is very critical for Brotli adoption, there is huge variance between maximum and minimum compression for both size and time. This was never the case for gzip.

Microsoft's IIS has special settings that allow it to disable gzip compression if CPU goes higher than a certain amount. Ideally NGINX brotli extensions can learn from it and enable a setting that backs off on compression if load is too high due dynamic assets compression.

Overall, dealing with brotli compression requires that our web servers get smarter and more understanding of the huge variance CPU with between the various brotli compression levels.

CDNs should advertise their Brotli support

CDNs these days publish support for HTTP/2, usually on the front page. This is excellent and I am impressed that so many CDNs these days ship with H2 support.

Brotli support on the other hand is a completely hidden item. It is not advertised anywhere. Given the huge compression benefits for the web, I hope CDNs can begin address advertising their Brotli support soon. I hope the community can start collating a list, say on where people shopping for CDNs can decide based on Brotli support.

Additionally there is a big untapped market in the CDN world for adding Brotli compression to assets, like many CDNs do with gzip.

You can experiment with Brotli support for static assets today

At Discourse we now allow you to optionally precompile all your static assets as .br files. You can see this in action when you visit on latest Chrome.

These are assets that never change between deploys and are always consumed on the front page. You are very likely to also have these kind of assets; your common css file and common js file.

If you have control over your asset pipeline adding support is quite simple. NGINX support though slightly more complicated is straight forward. There are huge wins to be had with the new format and adopting it for "precompiled" assets is a huge win, especially on Android mobile.

If you can perform brotli 11 compression upfront on all your most common static assets you will see very large network performance gains on supporting browsers.

Hold off on fighting with Brotli support for dynamically generated requests unless you fit the correct profile

On-the-fly Brotli compression is an area that needs a lot of experimentation. It is not enough to flick the switch at level 5 and forget about it.

There is a clear win enabling brotli level 1 if you had gzip level 1 enabled.

There is a clear win enabling brotli level 5 if you were comfortable with the CPU cost of gzip level 9 on dynamic assets and have capacity. (in this case you can expect a 5-10% win size wise)

In some cases there is no clear win enabling brotli on dynamic content.

I will follow up this article with another properly addressing the question of on-the-fly brotli compression.

Lobby Microsoft and Apple to add Brotli support

It is unclear when Microsoft and Apple plan to adopt Brotli in their browsers. This is particularly important for mobile browsers where every byte count quite a lot!

Brotli is an exciting technology, which you can start adopting today, big thanks to Google, Jyrki Alakuijala and Zoltán Szabadka!

Big thank you to Zoltán, Ilya and Jeff for reviewing this this article.


7 months ago

Thanks! This was very informative.
I particularly liked the description of the review process. It gives me more confidence knowing the gzip authors blessed this new compression algorithm.

John-David Dalton 6 months ago
John-David Dalton

Be sure to upvote the uservoice entry for Brotli support in Microsoft Edge.

Uwe Trenkner 5 months ago
Uwe Trenkner

Good article!

Just one remark concerning brotli at level 11: In the linked Akamai article Tim noted "Changing the quality setting from "10" to "11" provides no improvement here, nor was improvement seen when testing a handful of individual files to verify the results."

I can confirm this from my own tests: brotli 11 does not seem to make anything smaller than brotli 10. But it is noticeably slower.

3 months ago

Since this article was written, Brotli has made it into the Apache web server. No news on support from nginx nor IIS yet.

Nate Berkopec 87 days ago
Nate Berkopec

It looks like CDN77 will actually do Brotli on-the-fly, and not just pass on from a Brotli-enabled origin.

Other than that, nothing has changed as far as Brotli support on CDNs from when this article was written.

Inian Parameshwaran 50 days ago
Inian Parameshwaran

I recently wrote up about how to enable Brotli on different CDNs, even when they dont support it yet using service workers here

That is how we enable Brotli support at Dexecure using standard CDNs.

Sam Saffron 48 days ago
Sam Saffron

@everConfusedGuy yes that is an interesting hack ... Inspired by this I implemented something to work around the CDN implementation as well today.

In Discourse.

If the ENV var COMPRESS_BROTLI is enabled (by default for us) we have some sophisticated code that works around the CDN limitation.

  • Anonymous cache has been amended to use "has brotli support on client" as one of its cache keys. (so there is no bleed between different clients)

  • If the server detects that the client supports brotli cause Accept-Encoding has br it rewrites the asset paths so they point at /brotli_asset/ prefixed path that hits a rails route for the origin.

Then our brotli supporting clients get an HTML page with

<script src=""></script>

Instead of

<script src=""></script>

Then all assets under brotli_asset path are served via pre-existing brotli compressed static files our asset pipeline compresses.

The end result is that the CDN thinks it asked as for a gz encoded file but in fact gets a br encoded file. The hack appears to work fine. Will monitor that no weirdness ensues.

cc @nateberkopec

Sam Saffron 45 days ago
Sam Saffron

Ilya Grigorik sparked a very interesting conversations on Twitter with John Graham-Cumming CEO of Cloudflare and Arthur Bergman CEO of Fastly regarding CDN Brotli support.

In a nutshell CDNs are scared of enabling brotli cause it can lead to doubling of cache sizes:

Since Twitter is a bit tough for discussion will try to outline proposed solutions here:

First, though, keep in mind, brotli adoption client side is enormous: to-date 55% of clients support Brotli and the number will grow soon since Edge just added support.

Possible solutions to "double caching" problem:

1. jgrahamc - normalize to br,gzip - serve best available, fetch from origin to fix cache

  • first client is gzip, warm cache with a gzip copy, serve gzip
  • second client is br, serve it gzip, do another request to origin to see if it has br, fix cache
  • third client is br, serve it br


  • CDN Cache friendly, you only cache data that is needed
  • No unneeded delays experienced by clients


  • Can be complex to build
  • First br client may get gzip
  • Doubles the amount of reqs the origin gets

2. My hack of doom, ignore accept-encoding on origin, use different URI paths for different supported encoding

Have server decide dynamically if the client is br or not br capable, br capable clients get asset paths that are brotli only


  • Works today on all CDNs
  • Efficient


  • Makes Ilya Grigorik cry
  • Deliberately ignores Internet protocols

3. Ask for br unconditionally, recompress to gzip if needed on CDN node


  • If origin does not support br this has 0 cost
  • Simple to deploy


  • You have to compress with gzip -9 on demand (otherwise you risk perf regressions against what source could provide)

4. Add another header on origin

Origin provides PROVIDES-ENCODING header with all responses.

If it PROVIDES-ENCODING of br,gzip CDN knows to ask for br or gzip if it is missing from cache


  • Trivial to deploy
  • Simple to understand
  • Efficient


  • Requires another header on the origin

Personally I feel the best way forward is adding support for PROVIDES-ENCODING, it is cleanest and allows all CDNs to operate very efficiently with minimal changes.

comments powered by Discourse