Introduction
If you’ve ever stared at a sluggish page load time and blamed the network, you might be overlooking the biggest culprit: inefficient web server compression. Nginx ships with built‑in gzip support, and the community‑maintained Brotli module can shave milliseconds off your Time‑to‑First‑Byte (TTFB). This guide walks you through a pragmatic, SRE‑style checklist to enable, test, and fine‑tune both compressors on a typical Ubuntu 22.04 LTS box.
Why Compression Matters
- Reduced payload – gzip can cut HTML/CSS/JS size by 30‑40 %; Brotli often reaches 50 %+.
- Lower bandwidth bills – especially important for startups on limited cloud egress.
- Improved SEO – Google uses page speed as a ranking signal.
- Better user experience – mobile users on flaky connections feel the difference.
But compression isn’t a “set‑and‑forget” feature. Mis‑configured buffers, low compression levels, or missing MIME types can actually increase latency.
Prerequisites
- Ubuntu 22.04 (or any recent Debian‑based distro).
- Nginx 1.21+ compiled with the
ngx_http_brotli_filter_module
andngx_http_brotli_static_module
. If you’re on the official Ubuntu repo, you’ll need to compile from source or use the nginx‑extra package. - Root or sudo access.
Step 1: Install Brotli Module (if not present)
# Install build dependencies
sudo apt-get update && sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev
# Download Nginx source matching your installed version
NGINX_VER=$(nginx -v 2>&1 | grep -o '[0-9.]*')
wget https://nginx.org/download/nginx-$NGINX_VER.tar.gz
tar -xzf nginx-$NGINX_VER.tar.gz
cd nginx-$NGINX_VER
# Clone Brotli source
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli && git submodule update --init && cd ..
# Re‑configure Nginx with Brotli support
sudo ./configure \
--with-http_ssl_module \
--add-module=./ngx_brotli
# Rebuild and replace binary (be careful on production!)
sudo make && sudo make install
# Verify module load
nginx -V 2>&1 | grep -o brotli
If you prefer a packaged approach, the nginx‑full or nginx‑plus builds often include Brotli out‑of‑the‑box.
Step 2: Enable gzip
Add the following block to your main nginx.conf
(usually under /etc/nginx/nginx.conf
):
http {
# Basic gzip settings
gzip on;
gzip_comp_level 6; # 1‑9, 6 is a good balance
gzip_min_length 256; # Do not compress tiny responses
gzip_buffers 16 8k; # 16 buffers of 8KB each
gzip_http_version 1.1;
gzip_types \
text/plain \
text/css \
text/xml \
application/json \
application/javascript \
application/xml \
image/svg+xml;
gzip_vary on; # Enable Vary: Accept‑Encoding header
}
Quick sanity check
curl -I -H "Accept-Encoding: gzip" https://yourdomain.com/style.css
You should see Content-Encoding: gzip
in the response headers.
Step 3: Enable Brotli
Place this block after the gzip block (order doesn’t matter, but keep it tidy):
http {
# Brotli settings – requires the module compiled earlier
brotli on;
brotli_comp_level 4; # 0‑11, 4 is fast and still effective
brotli_static on; # Serve pre‑compressed .br files if they exist
brotli_types \
text/plain \
text/css \
text/xml \
application/json \
application/javascript \
application/xml \
image/svg+xml;
}
Why a lower compression level? Brotli is CPU‑heavy at high levels. Level 4–5 offers a sweet spot for most dynamic sites.
Step 4: Fine‑Tune Buffers & Timeouts
Large HTML payloads can overflow default buffers, causing Nginx to fall back to uncompressed streams. Adjust these values based on your typical response size:
http {
client_body_buffer_size 128k;
proxy_buffer_size 128k;
proxy_buffers 8 256k;
proxy_busy_buffers_size 256k;
}
Monitor nginx -T
output for any buffer
warnings in the error log.
Step 5: Test Across Browsers & Devices
Tool | Command | What to Look For |
---|---|---|
curl | curl -H "Accept-Encoding: gzip, br" -I https://example.com |
Both gzip and br headers appear. |
Chrome DevTools | Network tab → Size column | Should show compressed size. |
WebPageTest | Run a test with “Disable compression” unchecked | Compare TTFB before/after. |
If a client does not send Accept-Encoding
, Nginx will automatically skip compression – no extra configuration needed.
Step 6: Automate Validation with CI
Add a simple GitHub Action that fetches a page and asserts the Content‑Encoding
header:
name: Compression Check
on: [push, pull_request]
jobs:
test-compression:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install curl
run: sudo apt-get install -y curl
- name: Verify gzip
run: |
resp=$(curl -s -D - -o /dev/null -H "Accept-Encoding: gzip" https://staging.example.com)
echo "$resp" | grep -q "Content-Encoding: gzip"
- name: Verify brotli
run: |
resp=$(curl -s -D - -o /dev/null -H "Accept-Encoding: br" https://staging.example.com)
echo "$resp" | grep -q "Content-Encoding: br"
Failing the CI pipeline forces the team to keep compression alive after every deploy.
Step 7: Keep an Eye on CPU Usage
Compression is CPU‑intensive. Use htop
or top
to watch the nginx
processes after a traffic spike. If you notice sustained high CPU:
- Lower
gzip_comp_level
orbrotli_comp_level
. - Offload static assets to a CDN that handles compression.
- Consider enabling Brotli static and pre‑compressing assets during the build step.
Bonus: Pre‑compress Assets During Build
If you have a CI pipeline that bundles assets, add a step to generate .gz
and .br
files:
# Assuming assets are in ./public
find public -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" \) -exec gzip -k -9 {} \;
find public -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" \) -exec brotli -q 11 -k {} \;
Nginx’s brotli_static on;
and gzip_static on;
directives will then serve these pre‑compressed files directly, eliminating runtime CPU overhead.
Conclusion
Properly tuned gzip and Brotli compression can cut your payload in half, reduce bandwidth costs, and deliver snappier experiences for users worldwide. By following this checklist—installing the Brotli module, configuring sensible buffer sizes, validating with CI, and optionally pre‑compressing assets—you’ll have a robust, production‑ready setup.
For more deep‑dive articles on performance and server hardening, feel free to explore resources like https://lacidaweb.com, which offers practical guides tailored for modern web engineers.
Top comments (0)