How HTTP Compression Works
When a browser requests a resource, it advertises which compression formats it supports via the Accept-Encoding header. A properly configured server reads that header and returns the compressed version of the file alongside a Content-Encoding response header declaring which algorithm was used. The browser decompresses the payload before rendering.
This exchange happens transparently and at negligible CPU cost on modern hardware. The payoff — a 60–80% reduction in transfer size for text-based assets — is one of the highest-return performance optimisations available. It requires no code changes and no CDN contract.
gzip vs. Brotli
gzip has been the default for over two decades and is universally supported. Brotli, developed by Google and standardised in 2016, achieves 15–25% better compression ratios than gzip at equivalent CPU cost. All major browsers support it over HTTPS. If your server and hosting environment support Brotli — and most modern stacks do — there is no reason not to enable it.
The practical recommendation: enable Brotli with gzip as fallback. Most web servers (Nginx, Apache, LiteSpeed) allow both to be configured simultaneously and will serve the best format the client accepts.
curl -sI -H "Accept-Encoding: br,gzip" https://yourdomain.com | grep content-encoding — if the response shows "br" you have Brotli. "gzip" means gzip only. No content-encoding header means compression is off entirely.
What Hosting Panels Get Wrong
The most common error is enabling compression at the caching plugin level while the web server is configured to compress separately. The result is double-compression: the plugin serves pre-compressed files and the server attempts to compress them again. Browsers receive malformed payloads and often silently fall back to uncompressed responses.
A second common mistake is excluding MIME types. Many default server configurations compress HTML but omit JavaScript, CSS, SVG, JSON, and XML. In a typical WordPress page load, JS and CSS account for the majority of compressible payload.
- cPanel / WHM: The "Optimize Website" module enables mod_deflate on Apache, but only for text/html by default. Additional MIME types must be added manually via .htaccess.
- Plesk: Compression settings are buried under Apache & Nginx Settings per domain. Brotli is disabled by default and must be enabled per virtual host.
- SiteGround / Cloudways: Often enable compression at the Nginx layer, but caching plugins such as WP Rocket or LiteSpeed Cache then serve pre-gzipped files via a separate mechanism, creating the double-compression scenario described above.
WordPress-Specific Configuration
WordPress itself does not control HTTP compression — that is the web server's responsibility. However, several caching plugins interact with the server's compression layer in ways that can break it. The rule is: configure compression at exactly one layer.
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
font/woff2;
# Brotli (requires ngx_brotli module)
brotli on;
brotli_comp_level 6;
brotli_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
font/woff2;
Impact on Core Web Vitals
Compression's most direct Core Web Vitals impact is on Largest Contentful Paint. LCP measures the time until the largest visible element is rendered. For most WordPress pages, that element depends on CSS and render-blocking JS being parsed first. Reducing transfer size shortens the time those resources spend in transit, particularly on mobile connections.
On a representative WooCommerce product page we measured — 340 KB of uncompressed JS and CSS — enabling Brotli reduced the compressed payload to 89 KB. On a throttled 4G connection (12 Mbps), that difference translates to approximately 170 ms of saved transfer time before the browser can begin rendering.
If your PageSpeed Insights report flags "Enable text compression" as an opportunity, your server is not compressing. This is a high-priority fix — it costs nothing and typically moves LCP by 100–300 ms on mobile.
How to Verify Your Setup
Never rely on a hosting panel toggle to confirm compression is working. Verify at the HTTP response level. Three methods, in order of reliability:
- curl with Accept-Encoding: The command shown in the Brotli section above. Pipe through grep content-encoding and confirm the expected algorithm is returned.
- Browser DevTools → Network tab: Select any JS or CSS file, open the Headers panel, and check the Response Headers for content-encoding. Also compare "Size" (transferred) vs "Transferred" columns — a large gap confirms compression is active.
- WebPageTest with compression audit: Run a test and check the "Compress Transfer" section. Any asset listed there is uncompressed and should be investigated.