Website Cache & Server-Side Cache: How Caching Works in WordPress

Affiliate disclosure v3.1
Affiliate disclosure v3.2 (mobile)

Checking website cache and server-side cache on the server that runs this site, WordPress page requests went down in order from the browser through CDN, page cache, OPcache and Redis, and stopped at the layer that had a copy. Page requests that came straight to the origin server got the HTML file built by WP Rocket directly from nginx and never went down to PHP or the database.

Ⅰ. WordPress Cache Structure

In computing, a cache is a technique for temporarily storing data so it can be accessed quickly, and on the web it works on the same principle and contributes greatly to performance.

Caching stores data so that when visitors open a website, the server doesn't have to build everything again each time; stored data loads quickly and page load time drops. This lowers server load and improves the user experience.

The caches used for WordPress requests fall into two branches: website cache and server-side cache. The HTTP caching standard, as MDN describes it, classifies a cache stored only in one visitor's browser as a private cache and CDN and proxy caches shared by many visitors as a shared cache; this post groups the two as website cache.

Page cache, OPcache and object cache are caches attached to the process of running WordPress inside the server. The HTTP standard has no category for them, and the official WordPress documentation, in its Advanced Administration Handbook, explains them as caching plugins (page cache), object cache and server cache (opcode caches such as OPcache).

🗂️ Caches a WordPress request passes through
├─ 🌐 Website cacheHTTP cache · MDN classification
│ ├─ private cacheBrowser cache
│ └─ shared cache
│ ├─ proxy cacheProxies on company or ISP networks
│ └─ managed cacheCDN · reverse proxy (Varnish)
└─ 🖥️ Server-side cacheClassification in the official WordPress docs
├─ Page cacheStatic HTML built by a caching plugin (WP Rocket)
├─ OPcacheopcode cache · PHP execution
└─ Object cacheData that remains after the request ends (Redis)

The full range of fields where caching is used is covered in the Cache: Definition and All Fields Where Caching Is Used post, and the four branches of performance optimization, including caching, in the Web Performance Optimization: Structure and Definition post.

In the simulator below, choose a cache in the left tree and press a chip to see which layer the request stops at. The first layer WordPress site owners turn on with a caching plugin is the page cache.

🧭 Cache Layer SimulatorExplanatory simulator
🗂️ Caches a WordPress request passes through
🧰 Request type
Browser cache
The HTTP cache stored in the visitor's browser. Choose [Image · CSS] and press [First visit] → [Visit again]: from the second time on, no request goes to the server.
HTTP cache headers
The rules the server uses to tell browsers and CDNs how long to store a copy. The header lines in the response log are real values received from a server running Nginx + Apache.
CDN · proxy cache
A copy shared by many visitors. Turn on [Use CDN] and press [First visit] → [Visit again]: the response ends at the edge.
Page cache
Stores the HTML that PHP built as a file. Press [Visit again] and the request doesn't go down to PHP and the database.
OPcache
Keeps compiled PHP bytecode in memory. In [Visit after editing the post], PHP runs again but compilation is skipped.
Object cache
Stores query results in Redis. In [Visit after editing the post], only the changed post data is read again from MariaDB.
Full flow
A request goes down from the top and stops at the first layer that has a copy.
LayerStored inWhat it storesNginx + Apache example
Browser cacheVisitor's deviceHTML · CSS · JS · images · fontsCSS · images 7 days
CDN · proxy cacheIn front of the server (edge · reverse proxy)Copies of pages · static filesBunny CDN
Page cacheServer disk · memoryHTML built by PHPWP Rocket + nginx
OPcacheServer memoryPHP bytecodePHP 8.3, JIT off
Object cacheServer memoryQuery results · objectsRedis
A demo simulator that runs only in your browser. The header lines in the response log were received on October 10, 2026 from a server running Nginx + Apache; values in parentheses, such as the ETag after editing, are examples.

Ⅱ. Website Cache

Website cache is the cache where, once the server says how to store a response through its response headers, the visitor's browser and CDNs or proxies store a copy as instructed. Typical headers are [Cache-Control], [ETag] and [Expires], and once the storage period is over, a conditional request ([304 Not Modified]) checks whether it has changed.

1️⃣ Browser Cache

Browser cache is the HTTP cache stored in the visitor's web browser. It keeps HTML, CSS, JavaScript, images and fonts, and when the same resource is requested again, it either doesn't go to the server at all or only checks whether it has changed.

The storage period is set by the server, not the visitor. The Nginx + Apache server below tells browsers to keep CSS and images for 7 days, and answers HTML pages without a period, so they're checked again on every visit.

📨 Measured response headersNginx + Apache setup · 2026-10-10
💻 Visitor's computerBrowser cache
──────▶① First requestGET /style.css
🖥️ Website serverNginx + Apache
💻 Visitor's computerBrowser cache
◀──────② File + storage instructionscache-control: max-age=604800
🖥️ Website serverNginx + Apache
③ The browser stores it for 7 days as instructed and sends no request to the server for visits in between.
💻 Visitor's computerBrowser cache
──────▶④ Check after it expiresIf-None-Match: "6ab12775-2ee8"
🖥️ Website serverNginx + Apache
💻 Visitor's computerBrowser cache
◀──────⑤ UnchangedHTTP/2 304 (no body)
🖥️ Website serverNginx + Apache
🖼️ CSS · images
cache-control: max-age=604800
expires: Sat, 17 Oct 2026 03:21:00 GMT
etag: "6ab12775-2ee8"
The browser uses 7 days as its window for reusing the stored copy without asking the server again.
📄 HTML page
etag: "6ac9298c-95575"
last-modified: Fri, 09 Oct 2026 17:51:08 GMT
No storage period is given, so on a return visit the browser first asks with the ETag whether it has changed.
When the same ETag is requested again, the server returns only [HTTP/2 304], with no body, and the browser keeps using its stored copy.

2️⃣ CDN · Proxy Cache

CDN and proxy caches sit between visitors and the origin server and are shared by many visitors. A forward proxy sits in front on the visitor's side, as in a corporate network, while reverse proxies and CDNs sit in front of the server and answer with a stored copy in place of the origin server.

A typical reverse proxy is Varnish Cache, and CDNs such as Bunny CDN and Akamai follow the same structure. With geo DNS, visitors in the origin server's region can connect straight to the origin server, while visitors in other regions get responses from a nearby CDN edge (e.g., Bunny CDN) that stores even the HTML.

👤 Visitor in the origin server's regionDNS returns the origin address
→
🖥️ Origin serverAnswers directly, without going through the CDN.
👤 Visitor in another regionDNS returns a nearby edge address
→
☁️ Bunny CDN edgeAnswers here if it has a copy of the HTML or file.
→
🖥️ Origin serverReached only when the edge has no copy.

The structure and benefits of a CDN are covered in the What Is a CDN? Reasons to Use a CDN and 5 Benefits post.

Ⅲ. Server-Side Cache

Server-side cache is the cache attached to the process in which WordPress builds a page after the request reaches the origin server. A server built with Nginx + Apache handles requests in the order below, and once an earlier step finds a copy, the later steps are skipped.

🅐 When the page cache has the fileMost page requests from visitors who aren't logged in
① nginx receives the requestThe web server receives the request that reached the origin server.
↓
1️⃣ Page cache ↓② Responds with the page cache filenginx sends the HTML file built by WP Rocket as is.x-rocket-nginx-serving-file: HIT
It ends without going through PHP · OPcache · Redis · MariaDB.
🅑 When the page cache has no fileFirst visit right after clearing the cache · login screen · AJAX requests
① nginx receives the requestThere's no file, so it hands off to Apache.
↓
2️⃣ OPcache ↓② PHP runs · OPcacheRuns WordPress PHP files as compiled bytecode.
↓
3️⃣ Object cache ↓③ Object cache (Redis)Stored query results and objects come from Redis.
↓
④ MariaDBIt queries only data that isn't in Redis, and reads frequently used data from the InnoDB buffer pool (memory).
↓
⑤ Response · page cache savedIt sends the finished HTML and WP Rocket saves it as a file, so the next request is handled as 🅐.
Based on an Nginx + Apache setup (hands off to Apache and PHP only when there's no page cache file), checked 2026-10-10.

Cloudways and ScalaHosting let you choose an Nginx + Apache setup as an option. On Cloudways you pick, per application, either the Hybrid stack (Nginx + Apache) or the Lightning stack (Nginx only), and on ScalaHosting you can turn on a setting in SPanel that puts Nginx in front of Apache.

🖥️ Hosts where you can choose Nginx + Apache
CloudwaysStack choice per application
Hybrid stackNginx + Apache
Lightning stackNginx only
Cloudways →
ScalaHostingSPanel web server settings
DefaultApache
Turn on NginxNginx + Apache
ScalaHosting →
CacheWhat it storesWhen it's stored
1️⃣ Page CacheFinished HTML page🅑 ⑤ WP Rocket saves it as a file when responding
2️⃣ OPcacheCompiled PHP code (bytecode)🅑 ② When a PHP file first runs
3️⃣ Object CachePieces of data such as query results and options🅑 ③ When WordPress first fetches the data

1️⃣ Page Cache

  • ↪️ Full-page cache or HTML cache

Page cache is also called full-page cache, and since what it stores is HTML, it's sometimes called HTML cache. It saves the whole web page built by PHP as a static HTML file, then sends that file for the same page request without running PHP. This is case 🅐 in the processing order above.

It's stored in server memory (RAM) or on disk (HDD/SSD): memory is fast but costly and limited in size, while disk has plenty of room but is relatively slow.

TypeExampleHow it stores and responds
Caching pluginWP Rocket · WP Super Cache · W3 Total Cache · Cache EnablerWordPress saves the page as an HTML file, and the web server sends that file.
Web server cacheNginx FastCGI Cache · LiteSpeed CacheThe web server stores the PHP response itself and sends it for the next request.
Reverse proxy cacheVarnishA cache server placed in front of the web server stores the page and responds.

With Nginx + Apache, nginx reads the HTML file built by WP Rocket directly and sends it, and the response header gets [x-rocket-nginx-serving-file: HIT]. The steps to turn on and configure page caching with WP Rocket are in the WP Rocket Setup Guide post.

2️⃣ OPcache

OPcache stores PHP code precompiled into bytecode in memory, so running the same file again skips the PHP parser. It has been built in since PHP 5.5, and APC and XCache, used in the past, don't support PHP 7 and are no longer used. This is step ② of 🅑 in the processing order above.

TypeStatusDescription
Zend OPcacheBuilt in since PHP 5.5The standard opcode cache in use today, turned on with [opcache.enable=1].
OPcache JITIncluded in OPcache since PHP 8Converts bytecode once more into machine code to run it; switched on and off with [opcache.jit].
APCDiscontinuedThe opcode cache used before OPcache; its data cache feature carried on in APCu.
XCacheDiscontinuedDoesn't support PHP 7.
WinCacheFor Windows (IIS) serversAn opcode cache the official WordPress documentation lists alongside OPcache.

OPcache is turned on with the PHP setting [opcache.enable=1], and JIT, added in PHP 8, can be turned off separately with [opcache.jit=disable]. Installation and setup are covered in the Zend OPcache: Concept, Installation and Configuration article.

3️⃣ Object Cache

Object cache stores database query results or computed objects in a memory store such as Redis or Memcached. By default WordPress remembers objects only within a single request; you need to attach a store like Redis for results to remain after the request ends. This is step ③ of 🅑 in the processing order above.

TypeCategoryPersists after the request?Description
WP_Object_CacheWordPress defaultNoA built-in cache that remembers only within a single request.
RedisObject cacheYesA separate memory store, connected through the Redis Object Cache plugin's drop-in.
MemcachedObject cacheYesA separate memory store.
APCuObject cacheYes (within the same server)Stores in shared memory used by PHP.
fileObject cacheYesStores as files on disk.
InnoDB buffer poolThe database's own cache · not an object cacheYesMySQL and MariaDB keep table data and indexes in memory.
Query cacheThe database's own cache · not an object cache—Removed in MySQL 8.0; still in MariaDB but off by default.

WordPress connects to Redis through the drop-in file ([object-cache.php]) that the Redis Object Cache plugin adds. The installation steps are in the Installing and Configuring Redis Cache for WordPress article.

🔢 FAQ & Recommended Content

An old copy left in the page cache or CDN is responding. Clear that post's cache in your caching plugin, and if you use a CDN, clear the CDN copy as well.

Page caching plugins like WP Rocket don't send stored pages to logged-in users by default. The admin screens and pages viewed while logged in are built fresh by PHP every time, and OPcache and object cache keep them fast.

In Chrome, press [Ctrl+Shift+R] ([Cmd+Shift+R] on Mac) to reload the current page without the cache. To clear all stored cache, go to [More] at the top right → [Delete browsing data] and choose [Cached images and files].

💾 Cache-related posts 10 posts
🗂️ Cache
📋 Cache: definition and all fields 📄 Website cache & server-side cache
📋 WP Rocket settings guide 📝 Zend OPcache 📝 Redis Cache 설치
📝 CDN이란? 📝 Varnish Cache
📋 WP Rocket speed test 📝 속도 개선 사례 📝 캐시 · 최적화 플러그인

ℹ️ Affiliate Disclosure
This site's content contains affiliate links. When a visitor buys a product or service through one of them, the site receives a commission from the seller. The amount the buyer pays(it goes down during event discounts ↓)does not go up. Posted prices, discounts, and stock reflect the time of writing and may differ, so confirm with the seller before buying. Products are chosen and reviewed by our own standards, and commissions do not affect the order or content of reviews.

Leave a Reply

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

Prove your humanity: 10   +   5   =