Enable GZIP & Brotli Compression to Speed Up Your Site
You run your site through PageSpeed Insights or GTmetrix and get flagged for "enable text compression." Your caching is on, your images are optimized, and the page still feels heavier than it should. Nine times out of ten, the actual web server - Apache, Nginx, or LiteSpeed - just isn't compressing the HTML, CSS, and JS before sending it over the wire. Here's how to check, fix it properly, and avoid the mistake that breaks file downloads.
Symptom: What You'll Actually See
This one rarely shows up as a broken page - it shows up as a speed audit warning or a slightly-too-large "transferred size" number in your browser's dev tools. Common signs:
- PageSpeed Insights or GTmetrix flags "Enable text compression" or "Serve resources using efficient encoding."
- The Network tab in Chrome DevTools shows a big gap between "Size" and "Content" for your HTML/CSS/JS - meaning nothing was compressed in transit.
- TTFB looks fine, caching is working, but total page weight is still higher than a similar competitor site.
- Occasionally the opposite problem: a downloaded ZIP or PDF arrives corrupted or won't open - a sign of double compression, which we'll cover below.
Cause: Compression Isn't the Same as Caching
It's easy to assume that once a caching plugin or CDN is active, compression is handled too. It isn't automatically. Caching decides whether the server has to regenerate a page; compression decides how much data gets sent once it does. They're independent settings, and either one can be off while the other looks fine.
The usual culprits:
- Apache:
mod_deflate(or the newermod_brotli) isn't loaded or isn't applied to the right MIME types in your.htaccess. - Nginx: the
gzipdirective is off by default in a lot of stock configs, and Brotli needs a separate module that isn't compiled in everywhere. - LiteSpeed / cPanel shared hosting: compression is often on at the server level already, but a caching plugin or CDN sitting in front can strip the
Content-Encodingheader if it's misconfigured. - Cloudflare or another CDN: if your DNS record is set to "DNS only" (grey cloud) instead of "Proxied" (orange cloud), Cloudflare never touches the traffic, so its automatic Brotli compression never kicks in.
Check What's Actually Happening Right Now
Before changing anything, confirm the current state with curl instead of guessing from a speed tool's summary:
curl -I -H "Accept-Encoding: gzip, br" https://yourdomain.com/
Look at the response headers. If you see content-encoding: br or content-encoding: gzip, compression is already active for that request - the speed tool may be flagging a different resource (a font, an image, or a third-party script you don't control). If there's no content-encoding header at all, that confirms the server is sending the file uncompressed.
The Fix, by Server Type
cPanel shared hosting (Apache/LiteSpeed)
Most Getwebup shared and reseller plans run LiteSpeed with compression enabled by default. If yours isn't, add this to the top of your site's .htaccess in File Manager:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE application/rss+xml application/xml
</IfModule>
Save, then re-run the curl command above to confirm content-encoding: gzip shows up. If your site uses LiteSpeed Cache, its Page Optimization > Tuning tab has a compression toggle too - check that it's not set to bypass the server default.
Apache (VPS or dedicated)
Confirm the module is loaded, then enable it in your virtual host or a global config file:
sudo a2enmod deflate
sudo a2enmod brotli # if available on your distro's Apache build
sudo systemctl restart apache2
Then add the same AddOutputFilterByType block shown above inside the virtual host, or in .htaccess if AllowOverride permits it for that directory.
Nginx
Add this to your server block or nginx.conf's http block:
gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types text/plain text/css application/javascript application/json
application/xml text/xml application/rss+xml image/svg+xml;
For Brotli on Nginx you need the ngx_brotli module compiled in (it isn't part of stock Nginx). If you're running our Nginx reverse proxy setup, it's worth adding at the same time you configure SSL. After editing, test the config before reloading:
sudo nginx -t && sudo systemctl reload nginx
Cloudflare or another CDN in front
If you're using our Cloudflare CDN setup, Brotli compression is automatic once the record is proxied (orange cloud) - there's nothing to toggle under Speed settings on the free plan. If it's still not applying, double-check the DNS record isn't set to "DNS only," and that your origin server isn't already sending a content-encoding header Cloudflare doesn't recognize and passes through unchanged.
The Mistake That Breaks Downloads: Double Compression
Once compression is on at the server, don't also gzip files yourself before uploading them - a pre-zipped CSS file that then gets compressed again by mod_deflate can arrive at the browser corrupted, which is why a ZIP, PDF, or already-compressed image download sometimes fails right after someone "turns on compression" for the whole site. The fix is to exclude already-compressed MIME types explicitly:
<IfModule mod_deflate.c>
SetEnvIfNoCase Request_URI \.(?:gz|zip|rar|7z|pdf|jpg|jpeg|png|webp|mp4)$ no-gzip
</IfModule>
This tells Apache to skip compression for file types that are either already compressed or won't benefit from it - images and video are the classic example, since re-compressing them wastes CPU for zero size reduction.
Prevention: Keep It Working
- Re-run the curl check after any migration, theme change, or CDN swap - compression config lives at the server level and doesn't automatically follow a site move.
- If you add a CDN later, verify it isn't silently stripping the origin's
Content-Encodingheader - some misconfigured proxies do this. - Keep the
Vary: Accept-Encodingheader intact if you're caching at the edge - without it, a CDN can serve a compressed response to a client that didn't ask for one, or vice versa. - Never gzip binary or already-compressed files manually before upload; let the server's MIME-type rules decide what gets compressed.
Compression is one of the few speed fixes that's genuinely free - no plugin, no extra server load worth mentioning, just smaller responses over the wire. Once it's confirmed active with curl, that PageSpeed warning should clear on the next audit.
Frequently asked questions
Is GZIP or Brotli compression better?
Brotli generally compresses 15-20% smaller than GZIP for text-based files at a similar CPU cost, and all modern browsers support it. Use Brotli when it's available and let it fall back to GZIP for older clients - most servers and CDNs handle that negotiation automatically based on the browser's Accept-Encoding header.
Will enabling compression slow down my server?
The CPU cost is small for typical text assets (HTML, CSS, JS, JSON) and is almost always worth the bandwidth and load-time savings. The one place to be careful is compressing already-binary files like images or video, which wastes CPU for no size benefit - exclude those MIME types explicitly.
Why does PageSpeed still flag 'enable text compression' after I fixed my server?
Check which specific resource is flagged - it's often a third-party script (analytics, ads, a font CDN) that you don't control, not your own server. Run the curl command against that exact resource URL to confirm whether it's your origin or an external host that's uncompressed.
Can compression break my site?
Rarely, but double-compressing already-compressed files (ZIPs, PDFs, images) can corrupt downloads. If files stopped opening right after you enabled compression site-wide, add a no-gzip exclusion rule for those MIME types.
Do I need to do anything special for WordPress?
No - WordPress doesn't handle compression itself, so the same server-level fixes apply whether you're running WordPress or a static site. If you use a caching plugin like LiteSpeed Cache, just make sure its compression setting isn't set to bypass or conflict with the server default.