Open-source project
SatelliteWP/rocket-nginx avatar
SatelliteWP/rocket-nginx

rocket-nginx serves WP Rocket's cache without booting WordPress

Rocket-Nginx is a Nginx configuration that makes WP-Rocket even faster by serving static pages directly without loading WordPress or PHP.

618 stars127 forksPHPMIT

At a glance

What is it?
rocket-nginx is an Nginx configuration for the WordPress cache plugin WP Rocket that hands cached files to Nginx directly, so a hit on a cached URL never reaches WordPress or PHP, and the price of that speed is that WordPress cron stops firing unless you replace it with a real one.
Who is it for?
rocket-nginx fits a site on WP Rocket with real traffic, where the difference between serving a page from disk and running WordPress to produce it is the difference between a cheap origin and an expensive one. It does not fit a site that is not already on WP Rocket, since the whole configuration is written around that plugin's cache layout, and it does not fit a site whose scheduled jobs quietly depend on traffic arriving.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 123 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The cache hit never reaches WordPress

rocket-nginx is an Nginx configuration for the WordPress cache plugin WP Rocket, and it enables Nginx to serve directly previously cached files without calling WordPress or any PHP.

That single sentence describes the whole value proposition. WP Rocket stores the rendered pages it caches as files on disk, and by default WordPress itself is what looks for them, which means a request for a cached page still boots the whole PHP stack to find a file that is already sitting there. This configuration moves that lookup into Nginx, so the request never reaches WordPress.

It does a second thing as well. It adds headers to cache CSS, JS and medias, so that the browser holds those assets rather than re-requesting them, which reduces requests to the web server.

The README addresses the obvious question of how good the configuration is by answering it with the strongest available evidence: WP Rocket themselves use it on their website. A cache plugin vendor shipping a configuration that makes their own product's pages load faster is a meaningful endorsement, and it also tells you the configuration is maintained in step with the plugin rather than being a one-off snippet.

The configuration was created by Maxime Jobin and is now maintained by SatelliteWP, a WordPress maintenance service near Montreal, Canada, which offers its service in both English and French and sponsors the project.

WP-Cron stops firing, and you have to replace it

The Before You Start section is the most important part of the README, and it is a consequence rather than a caveat.

Because the configuration's goal is to serve cached files directly without having to execute any PHP from WordPress, this may cause your scheduled jobs to not be called. The reason is that WP-Cron jobs are not real cron jobs, and are executed only when you have visits on your site. A cached page that never reaches WordPress never triggers a scheduled task, so the side effect is proportional to how much of your traffic is served from cache.

The documented fix is two steps. Disable the WordPress cron job by adding a line to wp-config.php:

code
    define( 'DISABLE_WP_CRON', true );

Then create a real cron job every fifteen minutes, which the documentation says should be enough for most websites. Three forms are offered:

code
    */15 * * * * wget -q -O - http://www.website.com/wp-cron.php?doing_wp_cron &>/dev/null
code
    */15 * * * * curl http://www.website.com/wp-cron.php?doing_wp_cron &>/dev/null
code
    */15 * * * * cd /home/user/public_html; php wp-cron.php &>/dev/null

The three are wget, curl and a direct PHP invocation from the document root. The last one avoids the web server entirely, which is the most robust of the three, since it does not depend on the site being reachable over HTTP at the moment cron fires.

The README ends that section with the right instruction: make sure you test that your tasks still run after this change. A silently dead cron is the classic failure mode of this kind of setup, and it is invisible until someone notices a report that has not been generated in a week.

Clone, generate, include, test, reload

Installation has a fixed sequence, and the middle of it changed in version 2.0.

The configuration lives in your Nginx configuration directory, and on Ubuntu that is /etc/nginx. You clone the repository there:

code
  cd /etc/nginx
  git clone https://github.com/satellitewp/rocket-nginx.git

Since version 2.0 the configuration must be generated, and to generate the default configuration you rename the disabled ini file and run the configuration parser:

code
cd rocket-nginx
cp rocket-nginx.ini.disabled rocket-nginx.ini
php rocket-parser.php

That produces a default.conf configuration that can be included for all websites, and the ini file becomes the source of truth. The repository makes that explicit: the tree holds rocket-nginx.ini.disabled, the template rocket-nginx.tmpl and the parser rocket-parser.php, plus a tests/ directory.

Then the generated file is included from your Nginx configuration. If your site configurations live in /etc/nginx/sites-available, the include goes inside the server block:

code
server {
  ...
  
  # Rocket-Nginx configuration
  include rocket-nginx/conf.d/default.conf;
  
  ...
}

Before you reload, you test the configuration with nginx -t, and once the test is done you reload with service nginx reload.

One instance of Rocket-Nginx is needed for all your WordPress websites using WP Rocket, and you can generate as many configuration files as needed, so the work is once for one server rather than once per site.

The ini file is where you actually configure it

The Configuration section opens with a blunt statement: there is no configuration to do, it will work out of the box, but you can edit a couple of things. The couple of things live in the rocket-nginx.ini file, which is where the options are listed.

You can add a new section based on the default configuration, and the example shows the syntax:

code
# This creates the new section and will generate a new configuration
[example.com : default]

# This will add a value to invalidate the cache with a cookie
cookie_invalidate[] = "my_custom_cookie"

A section is a site and a profile, and the cookie_invalidate entry is a good illustration of what belongs here, since it is the kind of rule that only makes sense for a particular site rather than for the whole server.

After editing the ini file you regenerate the Nginx configuration by running the parser again, and newly added or modified sections generate updated configuration files with a .conf suffix.

Then comes the part that trips people up. Each time you generate or regenerate the configuration files, you have to test it to make sure it did not produce any error with nginx -t, and then reload the configuration with service nginx reload. The README states this as a numbered sequence, twice, once for the initial setup and once for the edit cycle, which tells you that the generate step is not a complete operation on its own.

conf.d and the file name patterns that decide where a snippet lands

Starting at version 3.0, a conf.d folder is created, and for each different profile you create, a subfolder is created inside that folder. In it, you can create files that will be included within the generated configuration file.

The interesting mechanism is the file name pattern, because it decides where in the generated Nginx configuration your file is inserted. There are seven documented patterns, each tied to a point in the request or response path.

The start.*.conf pattern runs before Rocket-Nginx starts. The global.*.conf pattern is applied globally in every section. The http.*.conf pattern is placed in the HTTP section. The preprocess.*.conf pattern runs after all the variables to use are set. And then there are three that sit inside the generated rules for the asset types the configuration handles: css.*.conf in the CSS section, js.*.conf in the JS section, and media.*.conf in the Media section.

All of these files go in the conf.d/default/ directory of the default profile, and each one has a matching section in the generated configuration, so the naming is a contract between your file and the template rather than a convention.

This is the part that makes the configuration extensible without forking it. Adding a header, adding a rule for a specific asset type, or adding something that has to run before the cache logic is a matter of dropping a file with the right name into a folder, and the parser puts it in the right place. The cost is that the seven patterns are a small DSL that you have to learn, and the README is the only documentation of it.

Debugging with the debug flag and the response header

The Debug section answers the question a user will have after installing: how do I know that Nginx is really serving the file and not still calling PHP?

The answer is a flag in the ini file. You open rocket-nginx.ini and change the debug value from debug = false to debug = true, and the configuration then reports what it is doing. The documentation adds that a particular header is present no matter whether debug is set to true or false, which is the useful part, because it means you can check the behaviour of a production site with the flag off. The README stops mid-sentence there, so the name of the header is only given as X-Roc.

The design of that flag is sensible for a configuration that is installed once and then forgotten. A permanent debug mode would be a liability, since debug output on a busy site is both noisy and slow. A header that is always present and a flag that turns the detail on means you can check the mechanism on production traffic and only turn the detail on when something is wrong.

For anyone using this configuration, the habit worth forming is to check that header after installing, and to check it again after a WP Rocket configuration change, because a cache path that quietly stopped matching is the kind of problem that shows up as a stale site rather than as an error.

MIT terms, a version line with a long gap, and where this sits

The licence is MIT, with the license file at the repository root, and the project is maintained by a commercial WordPress maintenance company rather than by an individual, which is a reasonable arrangement for a configuration that many agencies deploy for their clients.

The release history shows a slow line. The recent tags are v3.1.2 published on 2026-06-22, v3.1.1 on 2025-08-29 and v3.1.0 on 2024-07-25, so there is a nearly ten month gap between v3.1.1 and v3.1.2 and a two year gap before that. The repository is not archived and the last push was on 2026-06-22, the same day as the newest release, so the tree is in step with the tag rather than running ahead of it.

The structural changes matter more than the patch numbers. Version 2.0 made the configuration generated rather than static, and version 3.0 introduced the conf.d folder and the include patterns. Both are the kind of change that requires a migration, and both happened at a major version, which is the right way to make them.

The alternative approaches differ in what they cache and where. A full page cache served by Nginx is what this does, and the usual alternatives are a Varnish or CDN layer in front of the site, or a different WordPress cache plugin that ships its own Nginx integration. The difference in approach is that a CDN or Varnish sits in front of the origin and adds a network hop, while this configuration removes work from the origin by making the origin itself a static file server for cached pages. The tradeoff is the same one this project accepts: nothing behind the cache runs, not even the cron.

Editorial conclusion

rocket-nginx fits a site on WP Rocket with real traffic, where the difference between serving a page from disk and running WordPress to produce it is the difference between a cheap origin and an expensive one. It does not fit a site that is not already on WP Rocket, since the whole configuration is written around that plugin's cache layout, and it does not fit a site whose scheduled jobs quietly depend on traffic arriving. Before installing, set DISABLE_WP_CRON and add a real cron entry, because the README is explicit that otherwise your scheduled jobs stop being called, and keep the nginx -t step in the loop, since every regeneration of the configuration needs a test and a reload before it takes effect.

Frequently asked questions

What does rocket-nginx actually do?

It is an Nginx configuration for the WP Rocket WordPress cache plugin that enables Nginx to serve previously cached files directly, without calling WordPress or any PHP, and it adds headers to cache CSS, JS and media so the browser cache is used and requests to the web server are reduced.

Why do I need to disable WP-Cron when using rocket-nginx?

Because the configuration serves cached files without executing any PHP from WordPress, and WP-Cron jobs are only executed when you have visits on your site, so your scheduled jobs may stop being called. The README suggests disabling WordPress cron with define( 'DISABLE_WP_CRON', true ) and adding a real cron job every fifteen minutes, and says to test that your tasks still run afterwards.

How do I install rocket-nginx?

Clone the repository into your Nginx configuration directory, for example /etc/nginx on Ubuntu, then since version 2.0 rename rocket-nginx.ini.disabled to rocket-nginx.ini and run php rocket-parser.php to generate the default.conf file, include rocket-nginx/conf.d/default.conf in your server block, and finally test with nginx -t and reload with service nginx reload.

How do I customise the configuration?

Edit the rocket-nginx.ini file, adding a section such as [example.com : default] and settings like cookie_invalidate[] = "my_custom_cookie", then regenerate the configuration with php rocket-parser.php, test it with nginx -t and reload the configuration with service nginx reload each time you regenerate.

What licence is rocket-nginx under and how current is it?

It is released under the MIT licence, with the license file at the repository root. The recent releases are v3.1.2 on 2026-06-22, v3.1.1 on 2025-08-29 and v3.1.0 on 2024-07-25, and the configuration is created by Maxime Jobin and maintained by SatelliteWP.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. SatelliteWP/rocket-nginx on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/satellitewp-rocket-nginx.svg)](https://hysenlabs.com/projects/satellitewp-rocket-nginx)

Was this useful?