Brotli compression reduces the size of HTML, CSS, JavaScript, JSON, XML, and SVG responses before Nginx sends them to the client, which cuts bandwidth use and improves transfer time for text-heavy sites and APIs.

When a client advertises Accept-Encoding: br and the response is eligible, Nginx returns Content-Encoding: br and should also return Vary: Accept-Encoding so caches keep compressed and uncompressed variants separate. Brotli and gzip can coexist; Nginx picks the best encoding the client supports for the response.

Current Debian and Ubuntu packages ship Brotli as dynamic Nginx modules instead of built-in core directives. Installing the packaged modules creates load stubs under /etc/nginx/modules-enabled/, so packaged builds usually do not need manual load_module lines. Compression still trades CPU for bandwidth, so start with moderate levels, keep the type list focused on text-like responses, and leave already-compressed formats out of scope.

Steps to enable Brotli compression in Nginx:

  1. Install the Brotli dynamic modules from the distro packages.
    $ sudo apt update
    $ sudo apt install --assume-yes libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static

    Current Debian and Ubuntu packages place /usr/lib/nginx/modules/ngx_http_brotli_filter_module.so/ and /usr/lib/nginx/modules/ngx_http_brotli_static_module.so/ on disk, then create /etc/nginx/modules-enabled/50-mod-http-brotli-filter.conf/ and /etc/nginx/modules-enabled/50-mod-http-brotli-static.conf/ so the modules load automatically.

    Install only the filter package if you want on-the-fly Brotli but do not plan to serve precompressed /file.br/ assets.

  2. Add Brotli directives inside the http block of /etc/nginx/nginx.conf or an included file loaded from that block.
    http {
        brotli on;
        brotli_comp_level 5;
        brotli_min_length 256;
        brotli_static on;
        brotli_types text/plain text/css text/javascript application/javascript application/json application/xml text/xml application/rss+xml application/atom+xml image/svg+xml;
        ##### snipped #####
    }

    text/html is compressed by default; brotli_types adds additional MIME types.

    brotli_static on serves precompressed /file.br/ siblings when they exist. If you did not install the static module or do not generate precompressed assets, leave that directive out.

  3. Test the Nginx configuration for syntax errors before reloading the service.
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

    If unknown directive "brotli" appears, the Brotli module is not loaded by the current build or the package install did not match the installed Nginx variant.

  4. Reload Nginx so the updated compression settings take effect.
    $ sudo systemctl reload nginx

    Use sudo nginx -s reload when the daemon is running without systemd, such as in some containers or hand-started test environments.

  5. Confirm that a text response is actually served with Brotli compression.
    $ curl -sSI -H 'Accept-Encoding: br' -H 'Host: example.com' http://127.0.0.1/ | grep -iE '^(vary|content-encoding|content-type):'
    Vary: Accept-Encoding
    Content-Encoding: br
    Content-Type: text/html; charset=UTF-8

    If Content-Encoding: br is missing, test a text URL that matches the active server block. Brotli will not be used for binary assets, responses smaller than brotli_min_length, or content types outside brotli_types.