Enable Text Compression In WordPress: My Gzip And Brotli Fix
To enable text compression in WordPress, you turn on Gzip or Brotli at the server or host level so HTML, CSS, and JavaScript ship 60 to 80 percent smaller. I check the content-encoding header first, then enable it through the host, the .htaccess or Nginx config, a cache plugin, or Cloudflare, and confirm the fix on every response type.
To enable text compression in WordPress, you turn on Gzip or Brotli at the server or host level so HTML, CSS, and JavaScript ship 60 to 80 percent smaller. I check the content-encoding header first, then enable it through the host, the .htaccess or Nginx config, a cache plugin, or Cloudflare, and confirm the fix on every response type. If I were checking this on a real site, I'd start with the page that earns traffic or money, confirm whether the issue is backend, frontend, content, or layout related, then apply one fix at a time.
What Is Text Compression In WordPress?
Text compression is the server shrinking your HTML, CSS, and JavaScript before it sends them over the wire, so a 200 KB stylesheet might arrive as 30 KB and paint sooner. The browser sends an Accept-Encoding header listing what it can decode, the server compresses the response with Gzip or Brotli, tags it with a content-encoding header, and the browser unpacks it on the other end. The user never sees any of this, they just get a smaller download.
When PageSpeed Insights flags "Enable text compression," it's telling you those text files are leaving your server raw, with no encoding applied. That's pure waste, because text compresses beautifully: repeated tags, class names, and whitespace are exactly what these algorithms eat for breakfast. Typical savings across a WordPress site land between 60 and 80 percent of total text transfer, and a single CSS or JS file often drops 70 to 90 percent on its own.
One thing to fix in your head early: this only touches text. Compression does nothing for your images, because JPEG, PNG, and WebP are already compressed, and re-running Gzip on them wastes CPU for almost no gain. Images are a separate job covered in my WordPress image optimization guide, and getting both right is the core of real WordPress speed optimization.
Why Does PageSpeed Flag Enable Text Compression?
PageSpeed flags it because uncompressed text directly inflates your download time and pushes back first paint, which hurts your Largest Contentful Paint. Lighthouse compares the raw byte size of each text response against what it'd weigh compressed, and when the gap is big enough it lists the file plus the kilobytes you'd save. That estimate is conservative, so the real-world win is usually larger.
The slowdown compounds on mobile, where bandwidth is tighter and latency is higher. Shipping an extra 150 KB of uncompressed CSS and JS on a 4G connection can add the better part of a second before anything renders, and that's a second you're handing straight to your bounce rate. I want LCP under 2.5 seconds on mobile, and uncompressed text is one of the cheapest blockers standing in the way.
It's also one of the few wins that's nearly free of risk. Unlike deferring scripts or stripping CSS, turning on compression rarely breaks anything visible, so it's a fix I apply on almost every audit before I touch the trickier stuff. If your scores are rough across the board, start with the broader Core Web Vitals picture, then come back and knock out compression as an early, safe gain.
Gzip Vs Brotli: Which One Should You Use?
Use Brotli if your host supports it, and fall back to Gzip if it doesn't, because Brotli compresses text roughly 15 to 25 percent smaller than Gzip at comparable settings. Gzip has been around since the 1990s and ships on basically every server on earth, which is why W3Techs data has it on the large majority of compressed sites. Brotli is newer, built by Google, and every modern browser decodes it.
The trade-off is CPU. Brotli at its highest quality level (11) is slower to compress than Gzip, so for dynamic, uncached responses some hosts run Brotli at a lower level or stick with Gzip to keep server load down. For static assets that get cached and served thousands of times, that one-time compression cost is irrelevant and Brotli wins easily. On Nginx I'll typically set brotli_comp_level 6 or gzip_comp_level 6 as the sweet spot between ratio and CPU.
Here's the honest answer most guides skip: you usually don't have to choose. A well-configured host or CDN serves Brotli to browsers that advertise br in their Accept-Encoding header and Gzip to the rest, automatically. So the practical decision isn't Gzip versus Brotli, it's making sure at least one of them is active. Zstandard (zstd) is a third option appearing on some stacks, faster for highly dynamic content, but it's still rare in WordPress hosting.
Which Files Does Text Compression Actually Affect?
Compression affects your text-based responses: HTML, CSS, JavaScript, JSON, XML, SVG, and your fonts in some cases. These are the MIME types worth compressing, because they're full of repetition the algorithm can collapse. The standard list I enable covers text/html, text/css, text/javascript, application/javascript, application/json, application/xml, and image/svg+xml.
What you leave alone matters just as much. Don't compress JPEG, PNG, GIF, WebP, MP4, or WOFF2 fonts, because they're already compressed formats and a second pass only burns CPU while sometimes making the file slightly larger. WOFF2 in particular already uses Brotli internally, so re-compressing it is pointless. Most server configs set a minimum size too, usually around 256 bytes, since compressing a tiny 50-byte response costs more overhead than it saves.
This is why compression and image work are two separate streams in any real optimization plan. Compression handles the code, image optimization handles the media, and a CDN sits in front of both. I keep them as distinct line items on my WordPress speed audit checklist so neither gets skipped or double-counted.
How Do You Check If Compression Is Already On?
Check the content-encoding response header, because that single line tells you the truth no matter what your plugins claim. Open Chrome DevTools, go to the Network tab, reload the page, click the main document or a CSS file, and look under Response Headers. If you see content-encoding: br you're on Brotli, content-encoding: gzip means Gzip, and if the header's missing entirely, nothing's compressed and that's your problem.
From the command line it's faster: run curl -H "Accept-Encoding: gzip, br" -I https://yoursite.com and read the content-encoding line in the output. I like curl because I can swap the Accept-Encoding value to confirm the server actually serves both Brotli and Gzip depending on what the client asks for, which a browser alone won't show you.
If you'd rather not touch the terminal, online checkers like GiftOfSpeed or KeyCDN's Brotli test will fetch your URL and report the encoding and the percentage saved. Just don't trust a cache plugin's green checkmark on its own, because plugins frequently report "enabled" while the host quietly serves uncompressed responses. The header is the only source of truth, and I verify it the same way during a full WordPress site audit.
How Do You Enable Compression Through Your Host?
Start with your host, because on most modern WordPress hosting compression is either already on or one toggle away, and the host level is the cleanest place for it. Managed hosts like Kinsta, WP Engine, SiteGround, and Cloudways enable Gzip or Brotli by default at the server, so before you edit any files, open a quick support chat and ask whether Brotli is active for your account.
If you're on cPanel shared hosting, there's usually a built-in "Optimize Website" tool under the Software section that enables Gzip site-wide without you touching .htaccess at all. LiteSpeed-based hosts get an even better deal: the server handles compression natively, and pairing it with the LiteSpeed Cache plugin gives you Brotli with almost no configuration. I walk through that combo in my LiteSpeed Cache settings guide.
The reason I push host-level first is reliability. When the server compresses everything, including dynamic responses your cache plugin never sees, you don't have to worry about gaps. If your host genuinely can't enable it (rare, but it happens on bargain shared plans), that's a real signal you're on the wrong tier, and I cover the broader symptoms in slow WordPress hosting.
How Do You Enable Gzip Or Brotli In .htaccess Or Nginx?
On Apache you add Gzip rules to .htaccess using the mod_deflate module, never the ancient mod_gzip, which is deprecated and misbehaves on modern servers. A working block uses AddOutputFilterByType DEFLATE for each MIME type: text/html, text/css, text/javascript, application/javascript, application/json, application/xml, and image/svg+xml. For Brotli on Apache you enable mod_brotli and swap in AddOutputFilterByType BROTLI_COMPRESS for the same types.
On Nginx you can't use .htaccess, so the rules go in your server block. Gzip needs gzip on; plus gzip_comp_level 6;, gzip_min_length 256;, gzip_vary on;, and a gzip_types line listing the MIME types. Brotli on Nginx requires the separate ngx_brotli module compiled in, then brotli on;, brotli_comp_level 6;, and brotli_min_length 256; with its own brotli_types list.
Two details save you a support ticket. Always add Vary: Accept-Encoding (it's gzip_vary on; on Nginx) so proxies and CDNs cache the compressed and uncompressed versions separately and never serve a Brotli response to a client that can't read it. And after any Nginx edit, run nginx -t to test the config before you reload, because a typo here takes the whole site down, not just compression. This is hands-on server work, so if you're not comfortable editing live config, it's a fair point to bring in a WordPress speed specialist.
Can A Cache Plugin Or Cloudflare Handle Compression?
Yes, and it's the most practical route on shared hosting where you can't touch server config. WP Rocket detects Apache or LiteSpeed and writes the Gzip rules into .htaccess for you automatically when you activate it, no manual editing required. W3 Total Cache exposes a Gzip toggle under its Browser Cache panel, and WP Super Cache and WP Fastest Cache offer similar options. The catch is that plugins can only do this on servers that allow it, so they're a convenience layer, not magic.
Cloudflare is my favorite fallback, because it compresses at the edge regardless of what your origin server does. Once your site routes through Cloudflare, it serves Brotli to capable browsers by default on the free plan, so even a host with zero compression suddenly ships compressed responses to most visitors. I set this up in detail in my Cloudflare for WordPress speed guide. Other CDNs like KeyCDN and BunnyCDN also do Brotli at the edge.
The thing to watch with the CDN route is that Cloudflare only compresses what passes through it. Responses served directly from your origin (some dynamic or bypassed requests) still depend on the server. That's why I prefer host-level compression as the base and treat the CDN as a second layer rather than the only one. Dial in the rest of your caching with my cache plugin settings guide so the pieces don't fight each other.
What Mistakes Break Text Compression Fixes?
The most common one is assuming a cache plugin compresses everything. It doesn't. Cache plugins serve cached static HTML, but dynamic responses like the WordPress REST API, admin-ajax calls, cart fragments, and logged-in pages often skip the cache entirely and go out uncompressed unless the server itself handles compression. That's exactly why I keep insisting on host-level over plugin-only.
The second is double-compression, where the host compresses a response and then the CDN tries to compress it again. You end up with garbled output or a corrupted content-encoding header, and browsers throw decoding errors. If both your origin and Cloudflare are configured to compress, let one own it. Usually I leave compression on at the origin and let Cloudflare pass it through rather than re-encode.
The third is forgetting the Vary: Accept-Encoding header, which causes a proxy to cache a Brotli response and then hand it to an older client that can only read Gzip, producing broken pages for a slice of your visitors. And don't ignore dynamic responses just because the homepage tests fine. Test a few response types, not one. On WooCommerce especially, uncompressed cart and checkout responses add up, which I touch on in slow WooCommerce checkout.
How Do You Verify The Fix Actually Worked?
Recheck the content-encoding header on more than just the homepage, because compression can be on for static HTML and off for the assets that matter. I test the main document, a CSS file, a JavaScript file, and at least one dynamic response like a REST API endpoint, confirming each one returns br or gzip. If any of them come back bare, compression isn't fully enabled yet.
Then I rerun PageSpeed Insights and confirm the "Enable text compression" audit has cleared and moved into the passed checks. I run it on both mobile and desktop, because a CDN can compress for one path and miss another. The audit dropping off is the official confirmation, and I usually see a measurable bump in the performance score plus a smaller total byte weight in the network panel.
Last, I clear every cache layer before I trust the numbers: the cache plugin, the CDN, and the browser, in that order. Stale cached responses are the number one reason a correct fix looks like it failed. Once the headers are clean and PageSpeed's happy, this one stays fixed unless you migrate hosts, so I log it and move to the next item, often render-blocking resources or font optimization, which deliver the next biggest wins.
My checklist for Enable Text Compression in WordPress
whether Gzip or Brotli is active on the server
which text assets (HTML, CSS, JS) are sent uncompressed
whether the host or CDN handles compression