Your speed report says "Enable text compression" and you can't find the switch. Learning how to enable gzip compression takes about 5 minutes on most servers, and the payoff is real: HTML, CSS and JavaScript typically shrink by 60-75% before they leave your server.
Quick Answer: As of September 2026, the fastest route depends on your server. On cPanel, open Software → Optimize Website, choose "Compress All Content" and click Update Settings. On Nginx, add
gzip on;plus agzip_typeslist to your config and reload. On WordPress, compression belongs to the server, so fix it there. Then confirm acontent-encodingresponse header in your browser.
Last verified: September 2026, against Nginx 1.30.5 stable, Apache httpd 2.4 (mod_deflate), WordPress 7.1.2 and Cloudflare's current compression docs.
Our support engineers resolve 20 to 30 client site issues every day, and uncompressed pages turn up in that queue more often than you'd expect, usually after a server move or a copied snippet that never worked. This guide is the checklist we actually use, written so you can run it yourself.
Gzip is lossless. The browser unpacks the exact original file, so nothing about your design changes. It only helps text: HTML, CSS, JavaScript, JSON, SVG and web fonts. JPEG, PNG, WebP and video are already compressed, and gzipping them burns CPU for no gain.
Check If Gzip Is Enabled Before You Change Anything
Check first. Plenty of servers already compress, and stacking a second set of rules on top only creates conflicts.
The reliable way to check if gzip is enabled is the response header, not a green tick in a plugin. Open Chrome DevTools (F12), select the Network tab, reload, click the main document and look for content-encoding under Response Headers. A value of gzip, br or zstd means compression works. No header means the file left the server at full size, often 3-4 times heavier than it needed to be.
From a terminal, the same check takes 2 seconds:
bashcurl -sI -H "Accept-Encoding: gzip" https://example.com/ | grep -i content-encoding
Leave out that Accept-Encoding header and curl asks for an uncompressed file, so the server correctly sends one. According to Hostaccent's support team, which handles 20-30 client issues a day, that single missing flag explains a large share of the "gzip isn't working" reports we see: the server was fine, the test wasn't.
Test a stylesheet and a script as well as the homepage. PHP pages and static files often travel through different handlers, and we've seen plenty of sites where the HTML arrived compressed while a 300 KB theme bundle didn't. If you want the wider picture, our guide on how to check website speed and read the results shows where the "Enable text compression" audit sits in a full report.
Why does my browser say br or zstd instead of gzip?
Your browser announces every format it can decode in the Content-Encoding negotiation headers, and the server or CDN picks the best one. Behind a CDN you'll often see br (Brotli) or zstd (Zstandard) instead of gzip. That's compression working, not failing, so don't try to "fix" it.
Pro Tip: To see what your own server does, bypass the CDN. Point a hosts-file entry at the origin IP, or use
curl --resolve example.com:443:ORIGIN_IP, then repeat the header check. Edge and origin can behave very differently.
How to Enable Gzip Compression in cPanel
cPanel gives you two routes: the Optimize Website tool for a two-click fix, or .htaccess rules when you want control over exactly which file types get compressed.
Route 1: the cPanel Optimize Website tool
- Log in to cPanel and find the Software section.
- Click Optimize Website.
- Under Compress Content, change the default Disabled to Compress All Content.
- Click Update Settings, then rerun the header check above.
"Compress All Content" is safe to pick, because cPanel's rule already skips common image formats. On a cPanel server running Apache, enabling the Optimize Website option takes under 2 minutes and switches on mod_deflate for every text-based file in your account. One exception worth knowing: if the server runs LiteSpeed, compression is usually on by default and this toggle changes nothing.
Route 2: the .htaccess gzip deflate rules
If Optimize Website is missing or you need finer control, add this block near the top of the .htaccess file in public_html, above any # BEGIN WordPress line:
bash<IfModule mod_deflate.c> <IfModule mod_filter.c> AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml AddOutputFilterByType DEFLATE text/javascript application/javascript application/json AddOutputFilterByType DEFLATE application/xml application/rss+xml image/svg+xml AddOutputFilterByType DEFLATE font/ttf font/otf application/vnd.ms-fontobject </IfModule> </IfModule>
Why the nested mod_filter check? In Apache 2.4, AddOutputFilterByType lives in mod_filter, not mod_deflate. The Apache mod_deflate documentation covers the finer directives, such as compression level and buffer size. It's the same file that holds your 301 redirect rules in .htaccess, so edit carefully.
Now the gotcha most tutorials skip. Snippets that start with <IfModule mod_gzip.c> target an Apache 1.3-era module that modern servers don't load, so the whole block is silently ignored. No error, no compression. Across the 4,000+ sites Hostaccent has migrated since 2016, a dead mod_gzip block copied over from an old host is a pattern our team keeps running into.
Pro Tip: Download a copy of
.htaccessbefore you edit it. A single typo returns a 500 error for the whole site, and the exact line number shows up in your cPanel error log.
Still blocked at Cloudflare?
Send the error code, affected hostname, and recent DNS or SSL changes. We will separate edge, origin, firewall, and certificate causes before proposing work.
Enable Gzip in Nginx (Including Behind a Reverse Proxy)
Nginx has gzip built in, but it's off by default, and even when you switch it on it compresses only text/html until you list the other types.
Add this inside the http { } block of /etc/nginx/nginx.conf, or drop it into /etc/nginx/conf.d/compression.conf:
bashgzip on; gzip_comp_level 5; gzip_min_length 256; gzip_vary on; gzip_proxied any; gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/rss+xml image/svg+xml font/ttf font/otf;
Then test and reload with sudo nginx -t && sudo systemctl reload nginx.
A sensible Nginx gzip setup in 2026 uses compression level 5, a 256-byte minimum, gzip_vary on and an explicit gzip_types list covering CSS, JavaScript, JSON, XML, SVG and fonts. That combination typically cuts text payloads by 60-75% while keeping CPU overhead small, because levels above 6 add processing time for only a few percent of extra savings.
A few details matter more than they look:
- Don't add
text/htmltogzip_types. It's always compressed, and listing it makesnginx -twarn about a duplicate MIME type. gzip_vary onsendsVary: Accept-Encoding, so a cache never hands a compressed copy to a client that can't read it.gzip_proxied anymatters behind a load balancer. The default isoff, which means Nginx skips compression for requests that arrive through another proxy. Every setting is explained in the official Nginx gzip module docs.
What if Nginx sits in front of Apache?
Whichever layer faces the visitor decides. If Apache already sends a gzip response, Nginx passes it through untouched rather than compressing twice. So enable compression at one layer, and make that the outermost layer you control.
Enabling Gzip on WordPress Without Plugin Conflicts
WordPress doesn't compress anything itself; the web server does. The right fix is the cPanel or Nginx method above, with a plugin as a fallback only when your host gives you neither.
Caching plugins that offer an "enable gzip" checkbox usually just write mod_deflate rules into .htaccess. That works on Apache and LiteSpeed. On a pure Nginx server, .htaccess is never read, so the plugin reports compression as enabled while every file goes out at full size.
The second trap is double compression. PHP has its own zlib.output_compression setting in the MultiPHP INI Editor, and switching it on alongside server compression can produce Chrome's ERR_CONTENT_DECODING_FAILED. In our experience the fix is always the same: pick the server layer and turn the PHP setting off.
For a WordPress site on shared hosting, the correct gzip setup in 2026 is a single server-level rule (Optimize Website, .htaccess or Nginx), PHP's zlib compression left off, and a cache purge afterwards. Then test a logged-out page, because logged-in visits often skip the page cache and can give a misleading result within 5 minutes of the change.
Insider Insight: Compression is a speed fix, not a rankings fix. It helps Core Web Vitals, but if the real worry is that nobody finds the site, the reasons a website isn't getting traffic usually run deeper than page weight.
Gzip vs Brotli Compression: What a Tuned Server Already Does
Brotli usually beats gzip by roughly 15-20% on text files, and every current browser supports it. Most of the time you don't have to choose, though: a tuned setup serves Brotli or Zstandard to browsers that ask for it and falls back to gzip for everything else.
| Encoding | Typical text saving | Browser support | How you enable it |
|---|---|---|---|
| Gzip | 60-75% | Every browser | cPanel, .htaccess, gzip on in Nginx |
| Brotli | About 15-20% smaller than gzip | Chrome 50+, Firefox 44+, Safari 11+ | Apache mod_brotli, the third-party ngx_brotli module, or a CDN |
| Zstandard | Close to Brotli, faster to compress | Current Chrome, Edge and Firefox | Mostly at the CDN edge today |
As of September 2026, Cloudflare's content compression docs state that Free plan zones are compressed with Zstandard by default, Pro and Business plans with Brotli, and that Cloudflare asks your origin for br, gzip responses. They also note that only responses with a 200, 403 or 404 status get compressed at the edge.
On a Cloudflare, Nginx and Apache stack like the one Hostaccent runs, the sensible split is to let the edge handle Brotli and Zstandard for modern browsers while gzip stays switched on at the origin. That keeps the hop from Cloudflare to the server compressed too, and any request that bypasses the CDN still gets a small page.
One opinion worth holding firmly: don't push Brotli to level 11 on dynamic pages. The top levels are meant for files you precompress once at build time. For HTML generated on every request, levels 4-6 give nearly the same size at a fraction of the CPU cost.
Why Gzip Still Isn't Working: The Three-Layer Check
When the header still won't appear, test each layer in order from the visitor inwards. We call it the Three-Layer Check, and it finds the culprit in a few minutes instead of an afternoon of guessing.
- Edge (CDN). Compare the header at the CDN with the header at the origin. A
cache-control: no-transformheader from your server stops the CDN re-encoding responses, which is sometimes the hidden reason it looks "off". - Proxy (Nginx). Look for
gzip offin a site-level file overriding the global setting, a missinggzip_typeslist, orgzip_proxiedstill at its default. Remember.htaccesschanges do nothing here. - Origin (Apache and PHP). Run
apachectl -M | grep deflateto confirm mod_deflate is loaded, delete anymod_gzipblocks, and check that PHP's zlib compression isn't doubling up.
The Three-Layer Check is a 3-step test for missing compression: confirm the header at the CDN edge, then at the Nginx proxy, then at the Apache origin. The first layer that returns no content-encoding header is where the fix belongs, and in most cases it takes under 10 minutes to find.
Also rule out the innocent explanations. A response under 256 bytes, an image file, or a redirect status can all legitimately come back uncompressed.
Key takeaways
- Check the
content-encodingheader first, and always sendAccept-Encodingwhen testing with curl. - On cPanel, Optimize Website is the quickest fix;
.htaccessrules give finer control. - On Nginx, list your
gzip_typesand setgzip_varyandgzip_proxied. - Let the server compress WordPress, and never stack PHP zlib on top.
- Seeing
brorzstdmeans a CDN is doing better than gzip, not that something broke.
Your Next Step: A Host That Already Passes the Header Check
Now that you know how to enable gzip compression, and that a missing header is usually a layer problem rather than a broken server, you have two options: keep tuning configs yourself, or run your site where that checking comes with the plan. Hostaccent's Economy plan, $1.99/mo (it renews at the same $1.99/mo) puts your site on NVMe storage with 24/7 engineers who'll trace a missing header with you, at a UK-registered host that's been hosting since 2016 (UK-incorporated 2018). One honest caveat: Economy is sized for a single website, so if you run several, Standard at $4.58/mo fits better. When you're ready, start on the Economy plan and run the curl check on day one.
Frequently Asked Questions
How to enable gzip compression if my host doesn't use cPanel?
On Plesk, open the domain's Apache & nginx Settings and add the Nginx directives from this guide to the additional directives field. On DirectAdmin and most LiteSpeed servers, compression is usually on already, so run the header check before changing anything. With no server access at all, putting the site behind a CDN such as Cloudflare compresses responses at the edge, though the hop to your origin stays uncompressed.
Does gzip compression help SEO?
Indirectly. Google doesn't rank pages higher because they're compressed, but compression lowers transfer size, which improves loading metrics like Largest Contentful Paint, especially on mobile connections. PageSpeed Insights flags uncompressed text resources as a failed audit, and Google's own guidance says compression can cut transfer size by up to 90%. Treat it as a basic speed hygiene step that removes a drag on rankings rather than a way to climb them.
Should I gzip images and videos too?
No. JPEG, PNG, WebP, AVIF, MP4 and WOFF2 files are already compressed internally, so running gzip over them saves almost nothing and wastes CPU on every request. That's why cPanel's Compress All Content option skips common image types automatically. To make images lighter, resize and convert them to WebP or AVIF before uploading. Save gzip for text-based files: HTML, CSS, JavaScript, JSON, XML and SVG, where savings of 60-75% are normal.
Is Brotli always better than gzip?
For static files, usually yes, because Brotli produces files roughly 15-20% smaller and every current browser decodes it. For pages generated on each request, the answer is closer: high Brotli levels cost noticeably more CPU, while low levels perform about the same as gzip. The practical setup is Brotli for browsers that support it, gzip as the fallback, and a CDN handling Brotli at the edge if your server lacks the module.
Can enabling gzip break my website?
Rarely, and the failures are predictable. A typo in .htaccess returns a 500 error until you fix or remove the line. Running PHP zlib compression alongside server compression can double-encode responses, which browsers reject with a decoding error. Neither damages data; both are undone by reverting the change. Back up .htaccess first, make one change at a time, and rerun the header check after each so you know exactly which edit caused a problem.
What gzip compression level should I use?
Level 5 or 6 for almost every site. Gzip runs from 1 (fastest, largest files) to 9 (slowest, smallest files), and the size difference between 6 and 9 is typically only a few percent while CPU time climbs sharply. Compression happens on every uncached request, so that CPU cost adds up on busy servers. If you precompress static files once during a build, level 9 is fine there because the work happens only once.












Discussion
Have a question or tip about this topic? Share it below — your comment will appear after review.