If your WordPress HTML is cached but CSS, JavaScript, fonts, or images are still fetched as fresh files, W3 Total Cache is not necessarily broken. Page caching and static-file (browser) caching are separate layers. On a LEMP server, the usual cause is that W3 Total Cache’s generated Nginx rules are not present in the active server configuration, are in the wrong server block, or are being overridden by another cache layer. Verify an actual asset response, install the generated rules in the configuration Nginx really loaded, reload safely, then purge and retest every layer.
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
What “not cached” actually means
A WordPress request can pass through several independent caches. Confusing them is the reason many troubleshooting attempts appear to work while static assets remain uncached.
As an Amazon Associate I earn from qualifying purchases.
| Layer | What it stores | How to verify it |
|---|---|---|
| Browser cache | Static files such as CSS, JavaScript, fonts, and images on a visitor’s device | Inspect the asset response for Cache-Control, Expires, ETag, and the browser’s cache behavior |
| Page cache | A generated copy of a WordPress HTML page | Request a page and inspect page-cache headers or the response body; this does not prove that its assets are cacheable |
| Nginx or reverse-proxy cache | Responses retained by the web server or an upstream proxy | Check the effective Nginx configuration and any proxy cache-status headers |
| CDN cache | Copies of files held at distributed edge locations | Request the CDN hostname directly and inspect its status and cache headers |
For a meaningful test, open a real CSS, JavaScript, font, or image URL rather than only the page URL. A page-cache hit can coexist with Cache-Control: max-age=0 on every stylesheet. The asset response is the evidence that matters.
Why LEMP changes the W3 Total Cache setup
Apache can read per-directory .htaccess files. Nginx does not. The WordPress Nginx handbook states that Nginx has no directory-level configuration file equivalent to .htaccess or IIS’s web.config, and WordPress cannot automatically modify the server configuration to create rewrite rules.
#1 Best Overall
W3 Total Cache can generate the rules, but the plugin cannot make Nginx use them merely by writing a file somewhere in the WordPress directory. The rules must be copied into an included Nginx configuration file or the correct virtual-host block, and the running Nginx process must be reloaded after the change.
This distinction is especially important for Disk: Enhanced page caching. The cached HTML file is stored under a path such as /wp-content/w3tc/pgcache/, but Nginx must be told to look there before passing the request to WordPress. Without that ordering, PHP runs normally and the generated cache file is never served.
Primary failure: the generated rules are not in the active configuration
How the request should be routed
For a normal WordPress installation, the official Nginx example checks the W3 Total Cache page-cache path before the requested URI and before index.php. The essential ordering is represented by:
try_files /wp-content/w3tc/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?$args;
Use the complete block generated for your current W3 Total Cache settings; do not paste this single line into an arbitrary location and assume it is sufficient. If the location is missing, placed in another virtual host, or saved in a file that the running process does not include, URL rewriting and Disk: Enhanced page caching cannot intercept requests.
Why a file on disk is not proof
Operators often find a generated snippet in a document-root file and conclude that Nginx is using it. Nginx may instead be loading a distribution-wide file, a control-panel template, a different virtual host, or an include path that excludes the snippet. The effective configuration—not the file you expect to be active—is what determines behavior.
Repair the configuration safely
- Generate rules for the current settings. In WordPress administration, open Performance → Install and copy the Nginx rules W3 Total Cache displays. Regenerate them if you have changed page-cache, browser-cache, or CDN settings since the previous copy.
- Inspect what Nginx actually loaded. On the server, run
nginx -T. This prints the complete parsed configuration, including included files and server blocks. If your host supplies an equivalent command, use it. Search the output for the W3 Total Cachelocation,try_files, browser-cache directives, and the hostname serving the affected site. - Put the rules in the matching server block. Add the generated
locationand browser-cache rules to the virtual host that handles the requested hostname, or to an include file that this block explicitly loads. Preserve the ordering required by your host’s template. A rule in a default server block will not affect a separate site-specific block. - Run a configuration test. Use the host’s Nginx syntax/configuration test before applying anything. Do not reload a configuration that reports an error; correct the file path, braces, directives, or include order first.
- Reload Nginx. Reload the service through your host’s documented method so workers pick up the tested configuration. A generated file has no effect until the running process has read it.
- Empty W3 Total Cache. Purge the relevant page and browser caches from the plugin. If a reverse proxy or CDN is present, purge that layer as well; otherwise an old response can mask the repaired origin.
- Test a real asset twice. Use a private browser window and request an actual stylesheet, script, font, or image URL. Record
Cache-Control,Expires,ETag,Age, and any CDN cache-status header on a cold request and a repeat request.
Do not use a successful page load as the only verification. The goal is to observe the headers and cache status on the file that visitors are downloading.
Diagnose the symptom you see
| Observed result | Likely explanation | Next action |
|---|---|---|
Asset returns 200 with Cache-Control: max-age=0 or an equivalent no-cache policy |
Browser-cache rules are absent, overridden, or intentionally disabled | Inspect the active Nginx server block and every upstream proxy for a later or conflicting header directive; then retest the asset |
| HTML is cached, but CSS or JavaScript is not | Page cache works while browser-cache/static-location rules or CDN mapping do not | Check the asset response itself, the static-file locations, and whether URLs point to the intended origin or CDN hostname |
| W3 Total Cache reports “Page Cache URL rewriting is not working” | The generated Nginx rules are not included in the loaded configuration, or Nginx has not been reloaded | Use nginx -T, install the generated rules in the correct block, run a configuration test, and reload; Disk: Enhanced depends on those rewrites |
| New changes appear only after a manual purge | A browser, Nginx cache, reverse proxy, or CDN is retaining the old response | Identify each layer, purge each one, and compare headers before and after the purge |
| CDN hostname returns 404 or origin content | The CDN hostname, origin, or pull-zone mapping is not ready | Correct the CDN origin/mapping and pass an explicit asset test before investigating local browser-cache headers |
Keep Nginx and W3 Total Cache from fighting over headers
Nginx can handle gzip and browser caching directly. The WordPress Nginx guidance therefore recommends leaving those functions to Nginx rather than creating duplicate rules in a plugin. This is not a requirement to disable W3 Total Cache wholesale; it is a warning to establish one authoritative source for each header and compression decision.
How conflicting rules present
- A W3 Total Cache rule sets a long lifetime, while an upstream proxy replaces it with
max-age=0. - Nginx adds an
Expiresvalue that disagrees withCache-Control, making browser behavior difficult to predict. - Compression or header directives are duplicated in nested locations, so the response differs between a CSS file, an image, and a font.
- A CDN rewrites or strips origin headers, causing the browser response to differ from the origin response.
Inspect the final response seen by a client, not just the origin configuration. Once you know which layer adds each header, remove duplicate or contradictory directives and retest from a cold request.
Check CDN configuration independently
A CDN introduces another hostname and another cache. W3 Total Cache’s CDN procedure requires you to create or select the provider hostname, enable CDN functionality, test an asset such as http://cdn.domain.com/favicon.ico, and empty the cache. The exact test URL should use your own CDN hostname; the example illustrates that the test must request a real file.
If the asset test fails, local W3 Total Cache browser-cache settings cannot make the CDN ready. A 404 indicates a path or origin problem. A response containing origin content can indicate that the pull-zone mapping is wrong or that the edge is bypassing its cache. Fix the hostname and origin relationship first, then inspect cache headers from the CDN URL and the origin URL separately.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Version and environment checks
Record the installed W3 Total Cache version whenever you investigate this issue. The plugin’s current changelog includes fixes affecting browser-cache rewrite rendering and enhanced page caching on Nginx, so generated rules and settings can differ between releases. Also record the Nginx version, the host or control panel managing the virtual host, whether a reverse proxy is present, and whether a CDN rewrites asset URLs.
- After a plugin update, revisit Performance → Install and compare the generated Nginx rules with the active configuration.
- After a host migration or template change, rerun
nginx -T; the include path or server block may have changed. - When only one hostname fails, verify that its request is reaching the intended virtual host rather than a default server.
- When only one asset type fails, compare its location and headers with a working type; a nested Nginx location may be overriding the general browser-cache rule.
A repeatable verification checklist
- Confirm that the tested URL is a CSS, JavaScript, font, or image file, not only an HTML page.
- Separate page-cache results from browser-cache results.
- Run
nginx -Tand locate the exact active server block. - Confirm that W3 Total Cache’s generated
try_filesand browser-cache rules are included there. - Test the configuration, reload Nginx, and check the reload succeeded.
- Empty W3 Total Cache, browser, reverse-proxy, and CDN caches as applicable.
- Compare cold and repeat responses, recording
Cache-Control,Expires,ETag,Age, and CDN status headers. - If a CDN is involved, test its hostname directly before assigning blame to the origin.
This sequence distinguishes a missing rewrite from a header conflict and from a stale response. It also prevents a common false positive: seeing cached HTML and assuming every file referenced by that HTML is cached the same way.
Frequently Asked Questions
Does a cached WordPress page prove that my CSS and JavaScript are cached?
No. Page caching stores generated HTML, while browser caching stores static files. Inspect an actual asset response and its cache headers.
Recommended Free Tools
Can W3 Total Cache modify Nginx automatically like it does Apache?
No. Nginx does not read .htaccess. Copy the generated rules into the active Nginx configuration, test it, and reload Nginx.
What is the fastest way to find the configuration Nginx is using?
Run nginx -T (or your host’s equivalent) and search the parsed output for the site’s server block and W3 Total Cache directives.
Why does purging fix the problem temporarily?
A browser, Nginx cache, reverse proxy, or CDN may be serving an older response. Purging removes the symptom; identifying and correcting the retaining layer prevents it from returning.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →




