How To Enable Brotli Compression For WordPress On Apache

Ever look at your WordPress site’s HTML response size and think, “Why am I sending all this extra weight?” That’s how I end up enabling compression on most Apache setups I touch.

Brotli compression shrinks text files (HTML, CSS, JS, JSON, SVG) before they travel over the network. It’s like packing your suitcase with a vacuum bag instead of tossing everything in loose. On HTTPS, Brotli is usually the best option today, with gzip as a smart fallback for older clients.

In this guide, I’ll show you how to enable Brotli on Apache for WordPress, how to verify it’s working, and how to avoid the WordPress and CDN gotchas that waste time.

Make sure Brotli makes sense for your hosting setup

Before I change configs, I check one thing first: do I even have the access needed to enable Brotli?

On a VPS or dedicated server, you can install and enable mod_brotli. On shared hosting, you often can’t. Some hosts expose a toggle in cPanel, while others lock it down. If you’re on cPanel, this walkthrough on enabling gzip and Brotli in cPanel matches what I see in most modern hosting panels.

Next, I confirm the site is served over HTTPS. In 2026, browsers typically only advertise br (Brotli) on secure connections, so HTTPS is where Brotli really pays off. If your WordPress site still has mixed HTTP traffic, fix that first.

Finally, I sanity-check my caching stack:

  • If I’m using a page cache plugin, that’s fine. Apache still compresses the response it serves.
  • If a CDN sits in front (Cloudflare is the common one), the edge may already serve Brotli to visitors. That doesn’t mean the origin config is pointless, but it changes how I test (more on that below).
  • If I’m doing aggressive minification or combining files, Brotli still helps. It compresses the final output.

Safety note, because it matters: I always back up the config files and test on staging when possible. One small Apache syntax error can take every site on that server offline.

Apache configs to enable Brotli (with gzip fallback)

You’ll need mod_brotli plus a couple helper modules. On Debian/Ubuntu, I usually enable modules like this (names can vary by distro): a2enmod brotli headers filter deflate, then systemctl reload apache2. On RHEL-based systems, you’ll typically enable modules in the package and config.

Before reloading, I run a config check (apachectl configtest). After that, I prefer a reload over a restart because it’s less disruptive (systemctl reload apache2 or apachectl graceful).

1) Enable Brotli globally (server-wide)

Use this when you control the whole server and want a consistent default. Add it to your main Apache config (often apache2.conf or a global include like conf-enabled/*.conf).

<IfModule brotli_module>
  BrotliCompressionQuality 5
  BrotliWindowSize 16


  AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css
  AddOutputFilterByType BROTLI_COMPRESS text/javascript application/javascript application/json
  AddOutputFilterByType BROTLI_COMPRESS application/xml image/svg+xml
</IfModule>


<IfModule deflate_module>
  AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
  AddOutputFilterByType DEFLATE text/javascript application/javascript application/json
  AddOutputFilterByType DEFLATE application/xml image/svg+xml
</IfModule>


<IfModule headers_module>
  Header append Vary Accept-Encoding
</IfModule>

I keep the quality at 5 as a balanced starting point. Higher can shrink a bit more, but it costs CPU. If you want extra background reading on the fallback pattern, this article on Apache Brotli with gzip fallback lines up with how Apache negotiates encodings.

2) Enable Brotli per site (VirtualHost)

When I’m hosting multiple WordPress sites, I prefer per-site rules. It’s cleaner, and it avoids surprises.

Add this inside the relevant :443 VirtualHost:

<VirtualHost *:443>
  ServerName example.com


  <IfModule brotli_module>
    BrotliCompressionQuality 5
    AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css
    AddOutputFilterByType BROTLI_COMPRESS application/javascript application/json image/svg+xml
  </IfModule>


  <IfModule deflate_module>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
    AddOutputFilterByType DEFLATE application/javascript application/json image/svg+xml
  </IfModule>


  <IfModule headers_module>
    Header append Vary Accept-Encoding
  </IfModule>
</VirtualHost>

If you only do one thing, do this on HTTPS vhosts first. That’s where most traffic and support for br will be.

3) .htaccess option (only if your host allows it)

Some hosts let you use Brotli directives in .htaccess, many don’t. Even when they do, AllowOverride rules might block these directives.

If your host disallows Brotli in .htaccess, you’ll see a 500 error or the rules will be ignored. When in doubt, use the VirtualHost method or ask support to enable mod_brotli.

If it’s permitted, add this to the WordPress root .htaccess (usually the same file that has the WordPress rewrite rules):

<IfModule brotli_module>
  BrotliCompressionQuality 5
  AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css
  AddOutputFilterByType BROTLI_COMPRESS application/javascript application/json image/svg+xml
</IfModule>


<IfModule deflate_module>
  AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
  AddOutputFilterByType DEFLATE application/javascript application/json image/svg+xml
</IfModule>


<IfModule headers_module>
  Header append Vary Accept-Encoding
</IfModule>

That’s enough to enable brotli wordpress setups on Apache in a way that plays nicely with modern browsers and still serves gzip when needed.

Test Brotli, avoid double-compression headaches, and keep WordPress happy

After enabling Brotli, I verify it from the outside. Don’t trust “it should work.” Test it.

Quick verification checks

  • In Chrome DevTools, open Network, click your document request, and look for content-encoding: br.
  • From a terminal, try:
    • curl -I -H 'Accept-Encoding: br' https://example.com/
    • curl -I -H 'Accept-Encoding: gzip' https://example.com/

You want Content-Encoding: br for the first, and Content-Encoding: gzip for the second (or br again if the client asked for it). Also confirm you’re seeing Vary: Accept-Encoding, because caches need that to store both compressed and uncompressed variants safely.

WordPress performance gotchas I see a lot

If you use Cloudflare or another CDN, Brotli might be happening at the edge even if Apache is not doing it. That can make testing confusing. In that case, I test both with and without the CDN (or at least confirm what the browser actually receives).

Don’t worry about “double compression” in the literal sense. A response gets one Content-Encoding. The real risk is misconfiguring rules so caches serve the wrong variant, which is why Vary: Accept-Encoding matters.

Also, keep your scope tight. Only compress text-based types. Compressing images, PDFs, or already-compressed font formats wastes CPU and rarely helps.

Once Brotli is working, I often stack a couple WordPress-side wins. For example, cleaning assets and delivery can make compression even more effective. If you’re chasing better speed scores, these guides on eliminate render-blocking resources and remove query strings from static resources are two practical follow-ups.

If you want a broader checklist for WordPress speed work beyond compression, this WordPress performance guide is a solid reference.

Conclusion

Brotli is one of the cleanest wins you can add at the server level, because it makes every page lighter without changing your theme. Start with HTTPS vhosts, keep gzip enabled as fallback, and test with real headers before you move on. Once you see Content-Encoding: br in the wild, you’ve done the hard part, and your WordPress site will feel snappier for free.

Leave a Reply

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