Server & Hosting Tuning

How to Enable GZIP and Brotli Compression in WordPress (and Verify It’s Working)

Text compression is one of the oldest, cheapest speed wins there is, and it still gets skipped on a surprising number of WordPress sites I audit. The fix usually takes ten minutes. The catch is that “I turned it on” and “it’s actually working” are two different things — plugins claim to enable compression they can’t control, CDNs re-compress (or don’t), and server settings get overridden. So this guide covers both halves: enabling GZIP or Brotli properly, and proving it’s active.

What Text Compression Actually Does

When a visitor requests a page, your server sends back HTML, and the browser then pulls in CSS and JavaScript files. All of that is plain text — and plain text is highly repetitive. Stylesheets repeat the same property names hundreds of times; HTML repeats the same tags on every page. Compression exploits exactly that repetition, shrinking files before they’re sent and letting the browser decompress them on arrival, in milliseconds.

The practical effect: your HTML, CSS, and JS files commonly arrive at a third of their original size, sometimes less. On a slow connection, that’s a page that feels responsive instead of sluggish. It matters most for the initial HTML document, because nothing renders until that document arrives — so compression also improves the perceived TTFB and gets your Largest Contentful Paint started sooner. If your TTFB itself is high for server reasons, compression won’t rescue it (see my guide on fixing high TTFB in WordPress), but it does remove transfer time.

Two limits worth knowing. First, compression only applies to text — images, videos, and fonts are already compressed formats, and running them through GZIP gains nothing. Second, it only works if both sides agree: the browser sends an Accept-Encoding header listing what it supports, and the server picks from that list. Every modern browser supports both GZIP and Brotli, so in practice the server configuration is the only variable.

GZIP vs Brotli: Which Should You Use?

GZIP has been around since the early 1990s and is supported by every server and browser. Brotli is Google’s newer algorithm, released in 2015, and in day-to-day testing it typically produces files roughly 15–20% smaller than GZIP for HTML and CSS, thanks to a built-in dictionary of common web text and more compression levels (0–11, versus GZIP’s 1–9).

Two Brotli caveats:

  • HTTPS only. Browsers only accept Brotli over HTTPS connections. On a plain HTTP site, visitors silently fall back to GZIP.
  • Server support is less universal. GZIP ships with every Apache and Nginx install. Brotli needs mod_brotli on Apache (available since Apache 2.4.26, but not always enabled by your host) or a separate module on Nginx that most stock builds don’t include.

The pragmatic answer: enable both where you can. The server and browser negotiate automatically — Brotli-capable browsers get Brotli, everything else gets GZIP. If your stack only does GZIP, take it and move on; a working GZIP setup beats a broken Brotli one, and the gap between them is small compared to having no compression at all.

Step 1: Check Whether Compression Is Already On

Don’t configure anything until you know your starting point — plenty of hosts and CDNs enable compression by default, and stacking methods is how people end up with the double-compression problem covered at the end.

In your browser (Chrome/Edge/Firefox):

  1. Open your site, press F12, and go to the Network tab.
  2. Reload the page and click the first request (your domain — the HTML document).
  3. In the Headers panel, look under Response Headers for content-encoding: br means Brotli, gzip means GZIP, and if the line is missing entirely, that response is uncompressed.
  4. Click a CSS or JS file and check the same header — the HTML being compressed doesn’t guarantee your assets are.

While you’re there, compare the two size figures at the bottom of the Network panel — “transferred” versus “resources.” A big gap between them is compression doing its job.

From the command line, one request tells you everything:

curl -I -H "Accept-Encoding: br, gzip" https://yoursite.com

Look for content-encoding: br or content-encoding: gzip in the response.

Online checkers (such as GiftOfSpeed’s GZIP test) do the same thing without devtools, and PageSpeed Insights flags uncompressed text in its diagnostics — if it never mentions compression, you’re probably fine.

Step 2: Enable Compression at the Host or in cPanel

The cleanest place to enable compression is the server itself, because it then applies to everything — WordPress, static files, the lot.

In cPanel, look for Optimize Website (under the Software section). Set it to Compress All Content and save. This configures Apache’s mod_deflate and takes effect immediately. Not every host exposes this option, and on LiteSpeed or Nginx-based hosting it won’t exist at all — LiteSpeed servers typically have GZIP and Brotli enabled by default, and Nginx hosts handle it in the server config.

Hosts with custom panels usually put a compression toggle in their performance settings. If you can’t find one, ask support directly — “Is mod_deflate/mod_brotli active on my account?” — a two-line answer from them can save you an hour of experimenting.

Step 3: Enable Compression via .htaccess (Apache)

On Apache hosting without a control-panel option, you can enable GZIP by adding rules to your .htaccess file (in your WordPress root, next to wp-config.php). Back the file up first — a typo in .htaccess takes the whole site down, and this is the one step here where that’s a real risk.

# BEGIN GZIP compression
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/css
  AddOutputFilterByType DEFLATE application/javascript text/javascript
  AddOutputFilterByType DEFLATE application/json application/xml text/xml
  AddOutputFilterByType DEFLATE image/svg+xml font/ttf font/otf
</IfModule>
# END GZIP compression

Save, reload your site to confirm nothing broke, then re-check the content-encoding header from Step 1.

If your server runs Apache 2.4.26 or later with mod_brotli loaded, you can request Brotli instead — most setups serve Brotli to browsers that ask for it and fall back to GZIP otherwise:

# BEGIN Brotli compression
<IfModule mod_brotli.c>
  AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css
  AddOutputFilterByType BROTLI_COMPRESS application/javascript text/javascript
  AddOutputFilterByType BROTLI_COMPRESS application/json application/xml text/xml
  AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
</IfModule>
# END Brotli compression

If you add the Brotli block and the header still shows nothing, mod_brotli isn’t loaded on your account — remove the block, keep the GZIP version, and ask your host whether Brotli is available.

A Note for Nginx Sites

Nginx doesn’t use .htaccess at all, so plugin and file-based methods above do nothing there. Compression lives in the server config (nginx.conf or your site’s server block), which on shared or managed hosting only your host can edit. The relevant settings are:

gzip on;
gzip_types text/html text/css application/javascript application/json image/svg+xml;
gzip_min_length 1024;

Brotli on Nginx requires the ngx_brotli module, which isn’t part of the standard Nginx build — another reason Brotli availability is really a hosting question. If you’re on Nginx and compression is off, this is a support ticket, not a DIY job — though most Nginx-based hosts ship with GZIP already on.

Step 4: Enable Compression Through a Caching Plugin

If you already run a caching plugin, check what it’s doing before adding anything manually — this is where conflicting methods creep in.

WP Rocket handles compression at the server level rather than doing it itself: on Apache it writes the GZIP rules into your .htaccess automatically when activated. On Nginx it can’t, and leaves compression to the server or CDN. There’s no GZIP toggle in its settings to hunt for — if the Step 1 header check passes, WP Rocket’s part is done. (For how it stacks up against the alternatives, see my caching plugin comparison.)

LiteSpeed Cache works differently because it pairs with the LiteSpeed web server, where compression is a server feature. If you’re on LiteSpeed hosting, GZIP and Brotli are almost certainly already active at the server level — verify with the header check rather than assuming the plugin needs configuring.

The general rule: a plugin can only request compression via server rules it writes; it can’t compress anything itself on a server that doesn’t support it. When a plugin’s marketing says “enables GZIP,” read it as “adds the rules, if your server lets it.”

Step 5: Cloudflare Users — Check the Brotli Toggle

If your site runs through Cloudflare, compression happens at Cloudflare’s edge, and the setting is in your Cloudflare dashboard under Speed → Optimization (in newer dashboards, look under Settings → Content Optimization): a single Brotli toggle. Turn it on and Cloudflare serves Brotli to browsers that support it, GZIP to the rest.

Two things to understand about the CDN layer:

  • Cloudflare compresses responses as they pass through. If your origin also compresses, that’s normally fine — Cloudflare decompresses and re-compresses. It only goes wrong when a misconfigured origin sends already-compressed content with wrong headers, producing the double-encoding errors below.
  • Keep origin compression on anyway: cache misses and uncached pages (admin, checkout, logged-in views) still travel from your origin, and compression speeds those up.

And note that compression and caching headers are separate jobs — you still want proper cache rules for static assets, which I cover in the browser caching guide.

Step 6: Verify It’s Working (Really Verify)

Repeat the Step 1 header check for three requests: your homepage HTML, one CSS file, and one JS file. Each should show content-encoding: br or gzip. Then open the Network tab’s size figures and sanity-check that transferred size is well below resource size for your text assets.

If PageSpeed Insights flagged text compression before, re-run it — the warning should be gone. This is the step people skip, which is why so many sites “have GZIP enabled” for years without ever serving a compressed byte.

Troubleshooting

Both headers stacked (content-encoding: gzip, gzip or br, gzip). This is double compression: two layers — typically your server and a plugin, or your origin and the CDN — each compressed the response. Browsers usually decode it anyway, but it wastes CPU and can break some clients. Fix it by keeping compression in exactly one place per layer: server or plugin-written rules on the origin (not both), and let the CDN do its own thing at the edge.

You enabled it, but the header check shows nothing. Work through the usual suspects in order: a page cache serving an old uncompressed copy (purge all caches and retest); a CDN serving cached responses from before the change (purge the CDN too); you’re on Nginx and edited .htaccess (no effect — see the Nginx note above); or your host restricts mod_deflate on your plan, which only support can confirm.

Compression works on the homepage but not on assets. The rules you added probably only cover text/html. Make sure your mod_deflate block lists CSS and JavaScript MIME types, as in the snippet above — or, if a CDN serves your assets from a separate subdomain, check compression there separately.

Compression “breaks” a page or a tool complains. Rare, but a few security plugins and older minification plugins buffer output in ways that conflict with server compression. Disable the suspected plugin and retest to find the culprit. If a page renders as garbled text or downloads instead of displaying, that’s a mis-encoded response — remove the last compression change you made and re-add methods one at a time.

The Short Version

Check the content-encoding header first. If it’s missing, enable GZIP (and Brotli where available) in one place — host/cPanel if you can, .htaccess on Apache, a support ticket on Nginx, the toggle if you’re on Cloudflare — and then verify the header again on your HTML, CSS, and JS. Compression is a small win on its own, but it costs nothing, risks little, and applies to every page view. If you’ve done this and the site still feels slow, the bottleneck is elsewhere — work through this 15-minute diagnostic to find it.

Leave a Reply

Your email address will not be published. Required fields are marked *