Text-based HTTP responses — HTML, CSS, JavaScript, JSON, XML, SVG — compress dramatically with standard compression algorithms, often achieving 60–80% size reduction. Nginx supports two compression algorithms: gzip (built-in, universal browser support) and Brotli (via the ngx_brotli dynamic module, 15–20% better compression than gzip for text, supported by all modern browsers). Enabling compression is one of the highest-impact web performance optimisations: reducing a 120 KB JavaScript bundle to 30 KB over the wire means faster page loads, lower bandwidth costs, and better Core Web Vitals scores. On RHEL 9, gzip is compiled into Nginx; Brotli requires a dynamic module from EPEL. This guide covers enabling both gzip and Brotli in Nginx, configuring compression levels, excluding already-compressed files, and verifying compression is active with curl.
Prerequisites
- Nginx installed on RHEL 9
- EPEL repository enabled (for Brotli module)
Step 1 — Enable Gzip Compression
Add gzip configuration to the http block in /etc/nginx/nginx.conf:
vi /etc/nginx/nginx.conf
http {
# Enable gzip
gzip on;
gzip_comp_level 6; # 1 (fastest) to 9 (best compression). 5-6 is sweet spot
gzip_min_length 256; # Don't compress small responses
gzip_proxied any; # Compress proxied responses too
gzip_vary on; # Add Vary: Accept-Encoding header
gzip_buffers 16 8k;
gzip_http_version 1.1;
# Compress these MIME types
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/xml+rss
application/xhtml+xml
application/vnd.ms-fontobject
font/ttf
font/opentype
font/x-woff
image/svg+xml
image/x-icon;
# Never compress these (already compressed formats)
# gzip_types does not include image/jpeg, image/png, video/* by default
# application/gzip and application/zip are also excluded
}
nginx -t && systemctl reload nginx
Step 2 — Verify Gzip is Working
# The Accept-Encoding header tells Nginx the client accepts gzip
curl -H "Accept-Encoding: gzip" -I http://example.com/
# Look for: Content-Encoding: gzip in the response headers
# Download and decompress to verify
curl -H "Accept-Encoding: gzip" -s http://example.com/ | file -
# Should show: gzip compressed data
Step 3 — Install the Brotli Module
# Brotli module is available in EPEL
dnf install -y epel-release
dnf install -y nginx-mod-brotli
If the EPEL package is not available for your Nginx version, build from source:
# Alternative: build ngx_brotli as a dynamic module
dnf install -y gcc make git cmake
git clone https://github.com/google/ngx_brotli
cd ngx_brotli && git submodule update --init
NGINX_VER=$(nginx -v 2>&1 | grep -oP '[0-9]+.[0-9]+.[0-9]+')
curl -O https://nginx.org/download/nginx-${NGINX_VER}.tar.gz
tar xzf nginx-${NGINX_VER}.tar.gz
cd nginx-${NGINX_VER}
./configure --with-compat --add-dynamic-module=/usr/local/src/ngx_brotli
make modules
cp objs/ngx_http_brotli_filter_module.so /usr/lib64/nginx/modules/
cp objs/ngx_http_brotli_static_module.so /usr/lib64/nginx/modules/
Step 4 — Enable Brotli in Nginx
# At the top of /etc/nginx/nginx.conf
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
# In the http {} block
http {
# Brotli compression
brotli on;
brotli_comp_level 6; # 0 (fastest) to 11 (best). 6 is recommended
brotli_static on; # Serve pre-compressed .br files if available
brotli_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml;
}
nginx -t && systemctl reload nginx
Step 5 — Verify Brotli is Working
# Brotli uses the 'br' encoding token
curl -H "Accept-Encoding: br" -I https://example.com/
# Look for: Content-Encoding: br
# Compare sizes
curl -s -o /dev/null -w "%{size_download}n" http://example.com/
curl -s -H "Accept-Encoding: gzip" -o /dev/null -w "%{size_download}n" http://example.com/
curl -s -H "Accept-Encoding: br" -o /dev/null -w "%{size_download}n" https://example.com/
Step 6 — Pre-Compress Static Assets
For maximum performance, pre-compress static files at deployment time and serve the pre-compressed versions directly:
# Pre-compress CSS and JS files
find /var/www/example.com -type f ( -name "*.css" -o -name "*.js" ) | while read f; do
gzip -9 -k "$f" # Creates .gz file
brotli -9 "$f" # Creates .br file (install: dnf install brotli)
done
# Enable static module to serve pre-compressed files
# Add to server block:
location ~* .(css|js|html|json)$ {
gzip_static on; # Serve .gz if exists
brotli_static on; # Serve .br if exists
}
Conclusion
Gzip and Brotli compression in Nginx on RHEL 9 can reduce text response sizes by 60–80%, directly improving page load speed and reducing bandwidth costs. Brotli at level 6 achieves better compression ratios than gzip for text content and is supported by all modern browsers. The combination of on-the-fly compression and pre-compressed static files provides the optimal performance vs CPU balance.
Next steps: How to Configure Nginx FastCGI Caching on RHEL 9, How to Set Up Varnish Cache as a Reverse Proxy on RHEL 9, and How to Harden Nginx: Security Headers, TLS 1.3 and OCSP Stapling on RHEL 9.