Serve Cached Pages Directly from Nginx

Requires BerqWP v4 or higher.

When BerqWP optimizes a page on your site, it saves a pre-built copy of that page to your server’s disk. On nginx-powered servers, BerqWP can instruct nginx to serve that pre-built copy directly — without involving WordPress or PHP at all. This is called nginx page caching, and it’s the fastest way to deliver pages to visitors.

Think of it like this: normally, every visitor who lands on your site triggers a chain of PHP code before they see your page. With nginx page caching, nginx intercepts the request first, finds the pre-built copy BerqWP already prepared, and sends it straight to the visitor in milliseconds — skipping all of that work.


How to Enable Nginx Page Caching

Nginx page caching requires two things to be in place:

Step 1 — Make sure BerqWP is not in Sandbox Mode

BerqWP only builds and serves cached pages when Sandbox Mode is off.

  1. Go to BerqWP > Dashboard in your WordPress admin
  2. Look for the Sandbox Mode toggle
  3. If it’s enabled, switch it off and save
  4. BerqWP will begin building page cache automatically as visitors browse your site

Note: Sandbox Mode is useful for testing settings before they go live — but while it’s on, no cached pages are served to real visitors.

Step 2 — Make sure your server’s nginx config includes BerqWP’s rules

BerqWP writes the cached files, but nginx needs to know to look for them. This is done by adding BerqWP’s nginx rules to your server configuration.

Here are the nginx rules to add to your server configuration:

# BerqWP: pre-compressed cache delivery
location ~* /wp-content/cache/berqwp/.*\.html\.gz$ {
	types { }
	gzip off;
	default_type text/html;
	charset utf-8;
	add_header Content-Encoding gzip;
	add_header Vary "Accept-Encoding, Cookie";
	add_header Cache-Control "public, max-age=0, s-maxage=3600, must-revalidate";
	add_header X-served "server";
}

set $berqwp_cache "";

if ($query_string = "") {
	set $berqwp_cache "${document_root}/wp-content/cache/berqwp/html/${host}${uri}/index.html.gz";
}

if ($http_cookie ~* "(wp\-postpass|wordpress_logged_in|comment_author|woocommerce_cart_hash|edd_items_in_cart)") {
	set $berqwp_cache "";
}

if (-f $berqwp_cache) {
	rewrite ^ /wp-content/cache/berqwp/html/$host$uri/index.html.gz last;
}

Copy these rules and share them with your hosting provider — they’ll know where to add them. If you manage your own server (via GridPane, RunCloud, SpinupWP, or similar), add them to your site’s nginx configuration file inside the server {} block.

Not sure if your host uses nginx? Ask their support team: “Does my server run nginx, and can I add custom nginx location rules?” If they use Apache (common on shared hosting and cPanel), nginx page caching won’t be available — BerqWP will still cache pages via PHP, which is still fast.


How to Tell It’s Working

The easiest way to confirm nginx is serving your cached pages is to check for a specific response header.

Using your browser (Chrome/Firefox):

  1. Open your site in an incognito/private window (you must be logged out)
  2. Right-click on the page and choose Inspect
  3. Go to the Network tab
  4. Reload the page, then click on the first request in the list (your homepage URL)
  5. Look in the Response Headers section for:
X-served: server

If you see X-served: server, nginx is serving the cached page directly. If you see X-served: WP Hook instead, the page was served by PHP — nginx rules may not be in place yet.

Using the command line:

curl -I https://yoursite.com/

Look for X-served: server in the output.


What Gets Bypassed (Served Fresh from PHP)

Nginx page caching is designed to skip the cache automatically in situations where a cached page would be wrong for that visitor. You don’t need to configure any of this — it happens automatically.

Cache is not served to:

  • Logged-in users — WordPress admins, editors, and any user with a login session always get a fresh, uncached page
  • WooCommerce shoppers with items in their cart — the woocommerce_cart_hash cookie triggers a bypass so cart contents are always accurate
  • Easy Digital Downloads customers mid-checkout — the edd_items_in_cart cookie triggers a bypass
  • Comment authors — recent commenters see their comment immediately without a stale cached version
  • Password-protected pages — the wp-postpass cookie bypasses cache
  • Requests with query strings — URLs like ?utm_source=newsletter or ?s=search+term are not cached

When BerqWP Clears the Nginx Cache

BerqWP manages cache clearing automatically. You don’t need to manually flush the cache after routine edits — it handles that for you.

Cache is automatically cleared when:

  • A post or page is saved or updated
  • A new comment is approved on a post
  • You switch your WordPress theme
  • You trigger a full cache flush from the BerqWP admin bar or Dashboard
  • You change the BerqWP optimization mode
  • A new post is published (home page and related archive pages are cleared)

You can also manually clear cache at any time from the WordPress admin bar: click BerqWP > Flush Cache.


Troubleshooting

I see X-served: WP Hook instead of X-served: server

This means BerqWP is serving cached pages via PHP (the WordPress hook fallback), not via nginx directly. Most likely, the nginx rules for BerqWP haven’t been added to your server config yet. Check with your host or follow the setup guide for your hosting panel.

I don’t see any X-served header at all

You may be checking while logged in. Nginx cache is only served to logged-out visitors. Test in an incognito window, or use curl -I https://yoursite.com/ from a terminal.

My host uses Apache (cPanel, shared hosting)

Nginx page caching requires nginx. On Apache servers, BerqWP falls back to serving cached pages via PHP — which is still fast, just not as fast as nginx. If performance matters, consider migrating to an nginx-based host.

I enabled nginx rules but caching still isn’t working

Make sure Sandbox Mode is off (BerqWP > Dashboard). Also confirm that BerqWP has had time to build the cache — pages are cached on first visit, so try loading a few pages on the front end while logged out, then check the header again.

Another caching plugin is installed

Having two caching plugins active at the same time can cause conflicts. If you’re using WP Rocket, W3 Total Cache, LiteSpeed Cache, or any other caching plugin alongside BerqWP, deactivate the other plugin. BerqWP handles full-page caching on its own.


Advanced: The Nginx Rules Explained

For developers or server administrators, here’s what BerqWP’s nginx configuration does:

BerqWP stores cached pages at:

wp-content/cache/berqwp/html/{hostname}{uri}/index.html.gz

The nginx rules check whether a .gz cached file exists for the current request. If it does, nginx serves it directly with these headers:

add_header Content-Encoding gzip;
add_header Vary "Accept-Encoding, Cookie";
add_header Cache-Control "public, max-age=0, s-maxage=3600, must-revalidate";
add_header X-served "server";

If no cached file exists, the request falls through to WordPress as normal.

The bypass logic checks for the presence of any of these cookies before serving cache:

wp-postpass
wordpress_logged_in
comment_author
woocommerce_cart_hash
edd_items_in_cart

If any of these cookies are present, the cache is skipped entirely for that request.


Need Help?

If you’re having trouble setting up nginx page caching on your hosting environment, reach out to the BerqWP support team:

Offload Performance Headache to BerqWP

No configurations
Built for non techies
100% risk free
BerqWP v4 Dashboard