auto-brotli is a set-and-forget shell script that generates pre-compressed Brotli (.br) files
for static WordPress cache files.
It exists to solve one specific problem:
Brotli compression is expensive and should not be done on the fly.
Instead of compressing responses at request time, auto-brotli pre-compresses static cache files so your webserver can serve them instantly with zero CPU overhead.
Modern caching plugins (WP Rocket, WP Fastest Cache, etc.) already generate static HTML, CSS, JS, XML files on disk.
On-the-fly Brotli compression:
- is CPU intensive
- does not scale well under load
- increases TTFB during traffic spikes
Pre-compressed Brotli files:
- cost CPU once
- are served instantly
- scale perfectly
auto-brotli bridges that gap by continuously keeping .br files in sync with your cache.
auto-brotli is:
- a simple shell script
- incremental and idempotent
- designed to run via cron
auto-brotli is not:
- a daemon
- a file watcher
- a WordPress plugin
- a replacement for your cache plugin
It only pre-compresses files.
Your webserver is responsible for serving them.
-
Maximum compression
Uses Brotli quality level 11 for best compression ratio. -
Incremental operation
Only new or modified files are processed. -
Self-healing timestamps
.brfiles mirror ownership and modification times of their source files. -
Low system impact
Designed to run withniceandionicevia cron. -
Cache-cleaner friendly
Preserves file metadata so cache garbage collectors behave as expected.
- Linux system
brotliCLI tool installed- Debian / Ubuntu:
apt install brotli - RHEL / CentOS:
yum install brotli
- Debian / Ubuntu:
sudo wget -O /usr/local/bin/auto-brotli.sh https://raw.githubusercontent.com/realrellek/auto-brotli/main/auto-brotli.sh
sudo chmod +x /usr/local/bin/auto-brotli.shEdit the configuration at the top of the script:
-
WEB_ROOTBase directory containing your sites (e.g./var/wwwor/var/customers/webs) -
CACHE_PATH_PATTERNDefault:*/wp-content/cache/*
Compress all existing cache files once:
sudo /usr/local/bin/auto-brotli.sh --first-runFor large caches, use screen or tmux.
Recommended cron job (every 10 minutes, lowest priority):
*/10 * * * * /usr/bin/flock -n /tmp/auto-brotli.lock \
/usr/bin/nice -n 19 \
/usr/bin/ionice -c 3 \
/usr/local/bin/auto-brotli.shThis ensures:
- no parallel runs
- minimal CPU usage
- minimal disk IO impact
Requires ngx_brotli:
brotli_static on;That’s it.
Apache has no simple equivalent to brotli_static on.
You must explicitly rewrite requests to .br files and fix headers.
Example configuration:
<IfModule mod_headers.c>
RewriteCond %{HTTP:Accept-Encoding} br
RewriteCond %{REQUEST_FILENAME}\.br -s
RewriteRule ^(.*)$ $1\.br [L,QSA]
<FilesMatch "\.br$">
Header set Content-Encoding br
Header append Vary Accept-Encoding
</FilesMatch>
<FilesMatch "\.css\.br$">
ForceType text/css
</FilesMatch>
<FilesMatch "\.js\.br$">
ForceType application/javascript
</FilesMatch>
<FilesMatch "\.html\.br$">
ForceType text/html
</FilesMatch>
</IfModule>The webserver examples above are generic.
Caching plugins like WP Rocket use complex rewrite rules to bypass PHP.
You may need to adapt those rules to also check for .br files.
Refer to your caching plugin’s documentation when integrating Brotli static files.
- Primarily tested with WP Rocket
- Works with other disk-based cache plugins
- Edge case: if a cache file is deleted but its
.brfile remains, a stale response may be served until the cache is regenerated
With WP Rocket’s directory-based cache structure, this is usually not an issue.
When using WP Rocket, clearing the homepage cache may not remove existing
Brotli (.br) files if the homepage cache is not stored in a separate directory.
As a result, a stale .br file (for example index.html.br) may remain in place
and continue to be served by the webserver, even though the HTML cache was cleared.
This is not specific to auto-brotli — it is a side effect of how WP Rocket handles homepage cache cleanup.
You can fix this by hooking into WP Rocket’s cleanup action and explicitly removing
homepage .br files.
Add the following code to your theme’s functions.php, a plugin, or a mu-plugin:
add_action( 'after_rocket_clean_home', 'rellek_wpr_remove_home_br', 10, 2 );
function rellek_wpr_remove_home_br( $root, $lang ) {
if ( ! function_exists( 'rocket_direct_filesystem' ) ) {
return;
}
$files = glob( $root . '/*.br', GLOB_NOSORT );
if ( ! $files ) {
return;
}
foreach ( $files as $file ) {
if ( preg_match( '#/index(?:-.+\.|\.)html(?:_gzip)?\.br$#', $file ) ) {
rocket_direct_filesystem()->delete( $file );
}
}
}This ensures that stale homepage Brotli files are removed whenever the homepage cache is cleared.
auto-brotli can also be used to pre-compress non-WordPress files.
By adjusting:
WEB_ROOTCACHE_PATH_PATTERN
you can brotli-compress any static directory tree. Multiple copies of the script can be used for different targets.
MIT