Skip to content

Enable Brotli Compression on NGINX

Compress your content 15-25% better than gzip with Google's Brotli algorithm.


  • 15-25% Smaller


    Brotli achieves better compression ratios than gzip for text content

  • Universal Support


    All modern browsers support Brotli (Chrome, Firefox, Safari, Edge)

  • Faster Page Loads


    Smaller files = faster downloads, especially on mobile networks

  • Lower Bandwidth Costs


    Reduce data transfer costs with better compression


Browser Support

Brotli is supported by 95%+ of browsers worldwide:

Browser Brotli Support
Chrome ✅ Since v50 (2016)
Firefox ✅ Since v44 (2016)
Safari ✅ Since v11 (2017)
Edge ✅ Since v15 (2017)
Opera ✅ Since v38 (2016)

NGINX automatically falls back to gzip for older browsers.


Quick Setup

Step 1: Install the Brotli Module

# Install GetPageSpeed repository
dnf -y install https://extras.getpagespeed.com/release-latest.rpm

# Install Brotli module
dnf -y install nginx-module-brotli

Enable in /etc/nginx/nginx.conf:

load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

Step 2: Configure Brotli Compression

Create /etc/nginx/conf.d/brotli.conf:

# Enable Brotli compression
brotli on;
brotli_comp_level 6;
brotli_static on;

brotli_types
    text/plain
    text/css
    text/javascript
    text/xml
    application/javascript
    application/json
    application/xml
    application/xml+rss
    application/xhtml+xml
    application/atom+xml
    application/rss+xml
    application/x-javascript
    application/x-font-ttf
    application/x-font-opentype
    application/vnd.ms-fontobject
    font/ttf
    font/otf
    font/opentype
    font/woff
    font/woff2
    image/svg+xml
    image/x-icon;

Reload NGINX:

nginx -t && systemctl reload nginx

Step 3: Verify It's Working

# Request with Brotli support
curl -sI -H 'Accept-Encoding: br' https://example.com | grep -i encoding
# Content-Encoding: br

# Compare sizes
curl -so /dev/null -w '%{size_download}' -H 'Accept-Encoding: gzip' https://example.com
# 45678
curl -so /dev/null -w '%{size_download}' -H 'Accept-Encoding: br' https://example.com
# 38912  (smaller!)

Compression Levels

Level Speed Compression Use Case
1-3 Fast Lower High-traffic, CPU-constrained
4-6 Balanced Good Most websites (recommended)
7-9 Slower Better Pre-compressed static assets
10-11 Very slow Best Build-time compression only

Recommendation

Use level 4-6 for dynamic content and level 11 for pre-compressed static assets.


Pre-Compress Static Assets

For maximum performance, pre-compress files at build time:

# Install Brotli CLI tool
dnf -y install brotli

# Compress your static files
find /var/www/html -type f \( -name "*.css" -o -name "*.js" -o -name "*.html" -o -name "*.svg" \) \
    -exec brotli -kf --best {} \;

This creates .br files alongside originals. NGINX serves these automatically with brotli_static on.


Size Comparison

Real-world example (jQuery 3.6.0 minified):

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#009639', 'primaryTextColor': '#fff'}}}%%
pie showData
    title File Size Comparison
    "Original (89KB)" : 89
    "Gzip (31KB)" : 31
    "Brotli (27KB)" : 27
Format Size Savings
Original 89 KB
Gzip 31 KB 65%
Brotli 27 KB 70%

Advanced Configuration

Keep Gzip as Fallback

# Brotli (priority)
brotli on;
brotli_comp_level 6;

# Gzip (fallback)
gzip on;
gzip_comp_level 5;
gzip_types text/plain text/css application/javascript application/json;

Different Levels for Dynamic vs Static

# Dynamic content - faster compression
brotli on;
brotli_comp_level 4;

# Pre-compressed static files - best compression
brotli_static on;

Minimum Size Threshold

# Don't compress tiny files (not worth it)
brotli_min_length 256;

Troubleshooting

Brotli not working
  1. Check module is loaded:

    nginx -V 2>&1 | grep brotli
    

  2. Verify request includes Accept-Encoding: br

  3. Check response Content-Type is in brotli_types

CPU usage too high

Lower compression level:

brotli_comp_level 4;  # or even 2-3

Files not being compressed
  • Check file size > brotli_min_length
  • Verify Content-Type matches brotli_types
  • Check connection isn't already compressed (CDN)