Without caching, every page visit triggers the same expensive process: the server queries the database, executes PHP or application code, assembles HTML, and sends it to the browser. The browser then downloads CSS, JavaScript, images, and fonts from scratch. For a WordPress site, this means 20–50 database queries, PHP execution time, and dozens of HTTP requests — all repeated for every single visitor.
Caching stores the results of expensive operations so they can be reused. A page that takes 800ms to generate can be served in 10ms from cache. An image that takes 500ms to download can be loaded from the browser's local storage in under 5ms. Across an entire site, caching can improve performance by 10–50x.
This guide covers every caching layer: browser caching, server-side caching (page cache, opcode cache, object cache), and CDN edge caching. By the end, you'll understand how each layer works, when to use it, and exactly how to configure it.
The Caching Stack: Four Layers
Modern websites use multiple caching layers, each operating at a different point in the request-response cycle:
| Layer | What It Caches | Speed Benefit | Who Controls It |
|---|---|---|---|
| Browser Cache | CSS, JS, images, fonts | Instant (0ms network) | HTTP headers from server |
| CDN Edge Cache | Static assets + HTML pages | 10–30ms (from nearest PoP) | CDN configuration |
| Server Page Cache | Full HTML pages | 10–50ms (from disk/RAM) | Caching plugin or server config |
| Object Cache | Database queries, API results | 1–5ms (from RAM) | Redis/Memcached config |
Each layer reduces the work for the layers behind it. When all four are working together, a page that originally took 2 seconds to generate and download loads in under 200ms.
Layer 1: Browser Caching
Browser caching stores static files (CSS, JavaScript, images, fonts) on the visitor's device after their first visit. On subsequent page loads, the browser uses the local copy instead of downloading the file again. This eliminates network latency entirely for cached resources.
How It Works: Cache-Control Headers
Your server tells the browser how to cache files using HTTP headers. The most important header is Cache-Control:
Cache-Control: public, max-age=31536000, immutable
This tells the browser: "This file is cacheable by anyone (public), valid for 1 year (max-age=31536000 seconds), and will never change at this URL (immutable)."
Recommended Cache Durations
| Resource Type | Cache-Control | Cache-Busting Strategy |
|---|---|---|
| CSS (versioned) | max-age=31536000, immutable | Filename hash (style.abc123.css) |
| JavaScript (versioned) | max-age=31536000, immutable | Filename hash (app.xyz789.js) |
| Images | max-age=31536000 | Content-addressed URLs |
| Fonts | max-age=31536000, immutable | Versioned filenames |
| HTML pages | no-cache or max-age=300 | None (always revalidate) |
| API responses | no-store or max-age=60 | None (fresh data required) |
The key pattern is: cache static assets aggressively (1 year) and use filename hashing to bust the cache when you update them. When you change your CSS, your build tool generates a new filename (style.abc124.css), and the browser downloads the new version because it's a different URL. The old cached version simply expires.
Setting Cache Headers on Your Server
For Apache (.htaccess):
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
</IfModule>
For LiteSpeed and Nginx, similar directives control cache durations. Most caching plugins for WordPress handle these headers automatically.
Layer 2: Server-Side Page Caching
Server-side page caching stores the fully-rendered HTML output of a page. Instead of executing PHP, querying the database, and assembling HTML for every request, the server delivers a pre-built HTML file. This reduces TTFB from 400–800ms to 10–50ms.
How Page Caching Works
- First request: The server generates the page normally (database queries, PHP execution, template rendering). It saves the resulting HTML to disk or memory.
- Subsequent requests: The server checks if a cached version exists and is still valid. If so, it serves the cached HTML directly, skipping all processing.
- Cache invalidation: When content changes (new post, updated page, plugin activation), the cache is purged so the next request generates a fresh version.
Page Caching for WordPress
WordPress benefits enormously from page caching because each uncached page load typically involves 20–50 database queries. Popular caching solutions:
- LiteSpeed Cache — The best option if your host runs LiteSpeed web server. Server-level caching is faster than PHP-based alternatives because it's handled by the web server itself, before PHP even loads.
- WP Super Cache — Creates static HTML files from your dynamic WordPress pages. Simple and reliable.
- W3 Total Cache — Comprehensive caching plugin with page cache, browser cache, CDN integration, and database cache. More complex to configure but very powerful.
- WP Rocket — Premium plugin ($59/year) with the easiest setup. Great for non-technical users.
Serverlys Tip: Our cloud hosting runs on LiteSpeed, which means LiteSpeed Cache gives you server-level page caching out of the box. This is significantly faster than PHP-based caching plugins because the cache is served before PHP even loads. TTFB drops to under 50ms for cached pages.
What Not to Cache
Not everything should be cached. Exclude these from page caching:
- Logged-in user pages — Admin dashboards, account pages, and personalized content must be generated fresh.
- Shopping cart and checkout pages — Each user's cart is unique. Caching these would show other people's carts.
- Search results — Dynamic by nature, changing with every query.
- Recently updated pages — Use short TTLs or instant purging to ensure updates are visible immediately.
Layer 3: Object Caching (Redis / Memcached)
Object caching stores the results of database queries and expensive computations in memory (RAM). When a page needs data from the database, it checks the object cache first. If the data is there, it's served from RAM in 1–2ms instead of querying the database (which takes 5–50ms per query).
Redis vs. Memcached
| Feature | Redis | Memcached |
|---|---|---|
| Data persistence | Yes (survives restart) | No (RAM only) |
| Data types | Strings, lists, sets, hashes | Strings only |
| Performance | Slightly faster (single-threaded) | Good (multi-threaded) |
| WordPress support | Excellent (Redis Object Cache plugin) | Good (W3 Total Cache) |
| Recommendation | Preferred for most use cases | Good alternative if Redis unavailable |
For WordPress, Redis object caching typically reduces page generation time by 30–50% on uncached pages. On sites with complex queries (WooCommerce, membership sites, forums), the improvement can be even larger because these sites make hundreds of database queries per page.
Opcode Caching (OPcache)
OPcache is a PHP-level cache that stores compiled PHP bytecode in memory. Without it, PHP re-parses and compiles every .php file on every request. With OPcache enabled, compiled code is loaded from RAM, reducing PHP execution time by 2–3x.
OPcache is enabled by default on most modern hosting providers. You can verify it's active by checking phpinfo() or using a plugin like Query Monitor.
Layer 4: CDN Edge Caching
CDN edge caching stores your content on servers distributed worldwide, as we covered in our CDN setup guide. For caching purposes, the key considerations are:
Static Asset Caching at the Edge
CDNs automatically cache static assets (images, CSS, JS, fonts) based on your server's Cache-Control headers. Once cached at an edge server, these files are served to all visitors in that region without contacting your origin server.
Full-Page Edge Caching
Some CDNs can cache entire HTML pages at the edge. This means the CDN serves complete pages without your origin server being involved at all. TTFB drops to 10–30ms worldwide. For WordPress, plugins like LiteSpeed Cache (with QUIC.cloud CDN) or WP Cloudflare Super Page Cache enable this.
Cache Invalidation at the Edge
The hardest part of CDN caching is invalidation: when you update your site, the CDN's cached versions need to be updated too. Strategies include:
- Automatic purging via plugin — Best approach. The plugin notifies the CDN when content changes.
- TTL-based expiration — Set a short TTL (2–4 hours) so cached pages expire and get refreshed automatically.
- stale-while-revalidate — Serve the stale cached version while fetching a fresh one in the background. Users always get instant responses.
- Manual purge — Purge specific URLs or the entire cache through the CDN dashboard. Last resort for emergencies.
Putting It All Together: The Optimal Caching Stack
Here's the recommended caching configuration for a WordPress site on cloud hosting:
- Browser caching: Set 1-year max-age for versioned static assets. No-cache for HTML.
- CDN edge caching: Cache static assets for 30 days at the edge. Enable full-page edge caching with automatic purging.
- Server page caching: LiteSpeed Cache (if on LiteSpeed server) or WP Super Cache. Cache all public pages, exclude logged-in users and WooCommerce cart/checkout.
- Object caching: Redis with the Redis Object Cache plugin. Reduces database load by 50–80%.
- OPcache: Enabled by default on PHP 8.x. Verify it's active.
Performance Impact of Each Layer
| Caching Layer | TTFB Without | TTFB With | Improvement |
|---|---|---|---|
| No caching | 800ms | — | Baseline |
| + OPcache | 800ms | 500ms | 37% faster |
| + Object cache (Redis) | 500ms | 300ms | 40% faster |
| + Page cache | 300ms | 30ms | 90% faster |
| + CDN edge cache | 30ms | 15ms | 50% faster |
The combined effect is dramatic: from 800ms without any caching to 15ms with the full stack. That's a 53x improvement in server response time.
Serverlys Tip: Our cloud hosting comes with LiteSpeed server (for page caching), Redis (for object caching), OPcache (enabled by default), and CDN integration. You get the full caching stack without managing multiple services. See our plans.
Common Caching Mistakes
- Using multiple caching plugins. Running WP Super Cache and W3 Total Cache simultaneously causes conflicts. Use one page caching solution.
- Caching WooCommerce cart and checkout pages. These must be excluded from page caching. Most caching plugins detect WooCommerce and exclude these automatically, but verify.
- Not purging cache after updates. If you update your site but the cache still serves the old version, visitors see stale content. Set up automatic purging.
- Over-caching API responses. REST API endpoints that return dynamic data (stock levels, real-time prices) should not be aggressively cached. Use short TTLs or no caching for these.
- Ignoring mobile caching. If your site serves different HTML to mobile and desktop, your caching layer needs to maintain separate cached versions. LiteSpeed Cache handles this with "Mobile View" caching.
Frequently Asked Questions
How do I know if my caching is working?
Check HTTP response headers using Chrome DevTools (Network tab). Look for X-Cache: HIT (CDN cache), X-LiteSpeed-Cache: hit (LiteSpeed page cache), or similar headers from your caching solution. Also check TTFB: if it drops from 500ms to under 50ms, page caching is working.
Should I cache my site if I update content frequently?
Yes. Even sites that update hourly benefit from caching. Set a short TTL (5–15 minutes) or use automatic cache purging so updates appear quickly. Between updates, all visitors get the fast cached version. A news site that publishes every 30 minutes can still cache pages with a 5-minute TTL — that covers 99% of traffic.
Does caching work with personalized content?
Page caching works for the public, non-personalized parts of your site. For pages with personalized content (user dashboards, recommendations), use a combination of page caching for the shell and JavaScript-based loading for the personalized elements. This pattern is called "Cache, then personalize."
How do I clear my cache?
Most caching plugins have a "Purge All" button in the WordPress admin. For CDN caches, use the CDN provider's dashboard or API. For browser caches, you can't force visitors to clear theirs — which is why cache-busting with versioned filenames is essential for CSS and JavaScript.
Will caching cause problems with my site?
Properly configured caching is safe. Problems occur when dynamic pages (carts, user accounts) are cached when they shouldn't be, or when cache isn't purged after content updates. Start with the defaults of a well-maintained caching plugin, test your site, and only change settings if needed.