
September 12, 2026
10 min read
By Kokil Thapa | Last reviewed: September 2026
Every uncached HTML page, JSON API payload, and CSS bundle you send over the wire costs time on slow mobile networks in Nepal and abroad. When you compress responses with gzip and Brotli, the browser receives fewer bytes and paints the page sooner. That is not a cosmetic tweak. It directly affects Core Web Vitals and technical SEO because transfer size feeds into LCP and TTFB. On production Laravel, WordPress, and Symfony stacks I maintain, compression is one of the cheapest wins you can ship in an afternoon.
Why should you compress responses with gzip and Brotli?
HTTP compression shrinks text-based assets before they leave your server. The client sends an Accept-Encoding header. Your server picks gzip, Brotli (br), or sends raw bytes when compression is off.
Text compresses well. HTML, CSS, JavaScript, JSON, SVG, and XML often drop 60–80% in size. Images and video are already compressed, so do not waste CPU on them.
On a legal-tech portal I built, enabling Brotli cut a 180 KB HTML document to about 28 KB. PageSpeed scores moved without touching application code. That pattern repeats across content-heavy Laravel sites and WooCommerce stores.
Compression sits at the edge, not inside PHP. Laravel 13 and Symfony 8.1 generate the same HTML whether or not Nginx compresses it. That separation keeps your app simple and your server configuration reusable across projects.
How does gzip compare to Brotli for HTTP compression?
Both are lossless. Brotli typically beats gzip by 15–25% on text at similar CPU cost on modern hardware. gzip has been standard since HTTP/1.1 and every client supports it. Brotli is safe for all current browsers but not for very old ones.
| Criteria | gzip | Brotli |
|---|---|---|
| Compression ratio on HTML/CSS/JS | Good (60–75% reduction) | Better (70–85% reduction) |
| Browser support | Universal | All modern browsers since ~2016 |
| Server module | Built into Nginx and Apache | Requires ngx_brotli or mod_brotli |
| Precompression | Common (.gz static files) | Supported (.br static files) |
| CPU at high traffic | Lower per request | Slightly higher; cache helps |
| Best use case | Fallback for all clients | Primary for text assets |
Run both. Serve Brotli when Accept-Encoding: br is present. Fall back to gzip. Never double-compress already compressed files like JPEG or WebP.
How do you enable gzip and Brotli on Nginx?
Nginx ships with gzip. Brotli needs the ngx_brotli module compiled in or installed as a dynamic module on Ubuntu 22/24. After installation, add directives inside your server or http block.
gzip configuration
# /etc/nginx/nginx.conf or site conf
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
font/woff
font/woff2; gzip_vary on adds a Vary: Accept-Encoding header. Shared caches need that header to store separate variants. gzip_comp_level 5 balances CPU and ratio. Levels above 6 rarely help HTML.
Brotli configuration
brotli on;
brotli_comp_level 6;
brotli_min_length 256;
brotli_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
font/woff
font/woff2; Test the config and reload PHP-FPM's companion stack:
sudo nginx -t
sudo systemctl reload nginx Verify with curl:
curl -H "Accept-Encoding: br" -I https://example.com/
curl -H "Accept-Encoding: gzip" -I https://example.com/ Look for Content-Encoding: br or Content-Encoding: gzip in the response headers. The official Nginx gzip module documentation lists every directive if you need tuning details.
On Laravel apps behind Nginx, compression applies to Blade HTML, Vite-built assets, and Sanctum JSON responses alike. No PHP change is required. That is the same pattern I use on sister sites sharing a Deployer 7 pipeline.
How do you enable gzip and Brotli on Apache?
Apache uses mod_deflate for gzip. Brotli needs mod_brotli, available in Apache 2.4 on Ubuntu when the module package is installed.
Enable gzip with mod_deflate
# Enable modules
sudo a2enmod deflate
sudo a2enmod headers
# VirtualHost or .htaccess
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/json application/xml
AddOutputFilterByType DEFLATE image/svg+xml
Header append Vary Accept-Encoding
</IfModule> Enable Brotli with mod_brotli
sudo a2enmod brotli
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css
AddOutputFilterByType BROTLI_COMPRESS application/javascript
AddOutputFilterByType BROTLI_COMPRESS application/json application/xml
AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
</IfModule> Reload Apache after changes:
sudo apachectl configtest
sudo systemctl reload apache2 See the Apache mod_deflate reference for filter ordering and proxy edge cases. If you are migrating from Apache to Nginx, read our Apache to Nginx migration guide for a clean cutover.
What MIME types and file sizes should you compress?
Compress text. Skip binary formats that are already compressed. A common mistake is listing image/jpeg or font/woff2 — WOFF2 is pre-compressed and JPEG gains nothing.
- Always compress:
text/html,text/css,application/javascript,application/json,application/xml,image/svg+xml - Usually skip:
image/jpeg,image/png,image/webp,video/mp4,font/woff2 - Minimum size: 256 bytes — smaller responses cost more CPU than they save bandwidth
- API JSON: Large paginated payloads from REST APIs benefit heavily; see also Symfony serializer patterns for leaner payloads
For static assets built with Vite 8.x, precompress at build time. Generate .br and .gz files alongside your JS and CSS bundles. Nginx can serve them with gzip_static on and brotli_static on when the module supports it.
# Nginx static precompression
gzip_static on;
brotli_static on;
location ~* \.(js|css|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
} Build-time compression removes per-request CPU. On high-traffic WooCommerce shops, that difference matters during sale events.
How do you verify compression and avoid common production mistakes?
Verification belongs in every deploy checklist. I treat it like SSL checks — quick, repeatable, easy to automate.
- Open DevTools → Network → select a document → check Response Headers for
Content-Encoding - Run
curl -H "Accept-Encoding: br,gzip" -sI https://yoursite.com/and confirm encoding - Compare transferred size vs content length in DevTools
- Run Lighthouse or PageSpeed Insights and confirm "Enable text compression" is green
- Check CDN settings — Cloudflare and similar services can compress at the edge and hide missing origin config
Common failures I see on client projects:
- Double compression behind a CDN: Origin and CDN both compress, or neither does. Pick one layer.
- Missing Vary header: Cached gzip response served to a client that cannot decode it.
- Compressing images: Wastes CPU with zero byte savings.
- Proxy buffering off: Some Nginx proxy setups skip compression for upstream PHP responses unless
gzip_proxiedis set. - HTTP/2 and HTTP/3: Compression still applies to response bodies; HPACK/QPACK header compression is separate.
WordPress 7.1 and WooCommerce 11.1 sites on shared hosting often lack Brotli entirely. Moving to a VPS with Nginx and enabling both encodings is a standard step in our speed optimization service. Pair compression with Redis 8.10 object caching and proper browser cache headers for the full win.
PHP 8.5 and Laravel 13 do not need middleware for compression when the web server handles it. Avoid compressing inside PHP — you add latency and memory use for no benefit. Symfony 8.1 follows the same rule.
If you use a JSON formatter to inspect API output during development, remember that pretty-printed JSON compresses even better than minified JSON because repeated whitespace patterns compress well. Production APIs should still return compact JSON for clarity.
Key Takeaways
- Enable both Brotli and gzip at the web server — Brotli first, gzip as universal fallback.
- Compress text MIME types only; skip images, video, and WOFF2 fonts.
- Set
gzip_vary onand amin_lengthof 256 bytes to protect caches and CPU. - Precompress static Vite assets with
.brand.gzfiles for zero per-request cost. - Verify with curl and DevTools after every deploy — do not assume CDN defaults are correct.
- Combine compression with caching, CDN, and lean API payloads for maximum Core Web Vitals gain.
People Also Ask
Does gzip work with HTTP/2 and HTTP/3?
Yes. HTTP/2 and HTTP/3 compress response bodies with gzip or Brotli the same way HTTP/1.1 does. Header compression (HPACK or QPACK) is a separate mechanism. Enable body compression on your origin or CDN regardless of protocol version.
Should Laravel compress responses in middleware?
No. Let Nginx or Apache compress at the edge. PHP-level compression adds memory overhead and slows every request. Laravel 12 and 13 are designed to run behind a compressing reverse proxy.
Is Brotli worth it if gzip is already enabled?
Yes for text-heavy sites. Brotli saves an extra 15–25% over gzip on HTML and JavaScript. The module install is a one-time cost. CPU on modern servers is rarely the bottleneck for typical business traffic.
Can compression hurt SEO or Core Web Vitals?
Proper compression helps SEO by improving page speed signals. Google treats speed as a ranking factor. Smaller transfers improve LCP and TTFB. The only SEO risk is a misconfigured cache serving wrong encoding — fix that with the Vary: Accept-Encoding header.
Ship faster pages with gzip and Brotli today
When you compress responses with gzip and Brotli, you cut bandwidth, speed up pages on slow connections, and tick a major PageSpeed audit item — all without touching application code. The config takes minutes on Nginx or Apache. The gains last for every visitor.
If you want compression configured correctly alongside caching, CDN setup, and a full performance audit, see our testing and optimization service or browse the portfolio for live examples. For new builds, our web development team bakes compression into the server template from day one.
Contact us for a server audit, or read more on the blog about ongoing maintenance and production web systems built for Nepal and global clients.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

