WordPress Caching Layers on a VPS: Page Cache, Object Cache, and CDN, Explained

Hosting WordPress on a VPS gives you full control — and full responsibility for performance. A stock WordPress install runs dozens of PHP and database queries per page view, and on a small VPS that is a recipe for slow TTFB and CPU spikes. The fix is not one cache but a stack of them. This guide explains the four caching layers that matter on a VPS — OPcache, object cache, page cache, and CDN — in the order you should implement them, with the exact settings and commands for each.

Layer 1: OPcache (PHP Bytecode Cache)

Every PHP request recompiles your theme and plugin files unless OPcache is enabled. On PHP 8.x it ships built in; you just need to size it. In php.ini:

  • opcache.enable=1 — turn it on
  • opcache.memory_consumption=128 — enough for a typical plugin-heavy install
  • opcache.max_accelerated_files=10000 — covers most themes plus plugins
  • opcache.revalidate_freq=60 — check files for changes at most once a minute

Verify with php -i | grep opcache.enable after restarting PHP-FPM. This layer alone typically cuts PHP execution time by 30–50% with zero downside.

Layer 2: Object Cache with Redis

WordPress stores options, transients, and fragments of repeated queries in the database by default. An object cache keeps those in memory. On Debian/Ubuntu: sudo apt install -y redis-server php-redis, then install the Redis Object Cache plugin from the command line:

wp plugin install redis-cache --activate && wp redis enable

Use the Query Monitor plugin afterwards to check the cache hit rate — healthy installs see 80–95% of queries served from Redis instead of MySQL. Allocate 64–128 MB of Redis memory on a 1–2 GB VPS; that is more than enough for most sites.

Layer 3: Page Cache (Nginx FastCGI Cache)

Even with OPcache and Redis, every visit still runs PHP. A page cache stores the final HTML output so anonymous visitors never touch PHP at all. With nginx as your front server, FastCGI caching is the cleanest approach — no plugin needed. Key directives in your server block:

  • fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=wpcache:10m inactive=60m; — cache storage and zone
  • fastcgi_cache wpcache; — enable the cache for this server
  • fastcgi_cache_valid 200 60m; — cache successful pages for an hour
  • fastcgi_cache_bypass $http_cookie; — skip the cache for logged-in users (combined with a cookie check for comments/cart)
  • fastcgi_cache_purge — purge the page when a post is updated (via the nginx-helper plugin or a custom rule)

With this in place, anonymous page views produce a TTFB of 20–80 ms instead of 300–800 ms, and your PHP-FPM workers stay free for logged-in traffic and admin requests. Just remember to purge the cache on post updates — a stale homepage is worse than a slow one.

Layer 4: CDN for Static Assets

The final layer offloads JavaScript, CSS, images, and fonts to a CDN so your VPS only serves HTML and API traffic. Fingerprinted assets (with a hash in the filename) can be cached aggressively with Cache-Control: public, max-age=31536000. A CDN does not change server TTFB, but it dramatically improves first paint and time-to-interactive for visitors far from your data center, and it spares your VPS bandwidth and CPU on image-heavy pages.

LayerTypical effectEffort
OPcache−30–50% PHP execution time5 minutes
Object cache (Redis)80–95% fewer DB queries15 minutes
Page cache (FastCGI)TTFB 20–80 ms for anonymous visits30 minutes
CDNFaster global load, less VPS bandwidth1 hour

What Not to Cache

Caching the wrong responses is worse than caching nothing. Never serve cached pages to logged-in users, active commenters, or anyone with a WooCommerce cart — personalized content must bypass the page cache entirely. The standard nginx approach keys on cookies: fastcgi_cache_bypass $cookie_wordpress_logged_in; combined with fastcgi_cache_key "$scheme$request_method$host$request_uri$cookie_wordpress_logged_in";. Admin pages under /wp-admin/ should bypass as well. Set a short cache lifetime (5–15 minutes) for archive and taxonomy pages so recent posts appear quickly, and purge the cache whenever a post, page, or comment is published — the nginx-helper plugin wires WordPress hooks to purge endpoints automatically, and wp cache flush clears the object cache during deploys. Finally, exclude sitemap.xml and robots.txt from aggressive caching so search engines always see fresh metadata.

Putting It Together

Implement the layers in order and verify each one before moving on: curl -sI https://your-site/ | grep -E 'HTTP|x-cache' shows the page-cache header, Query Monitor confirms the Redis hit rate, and a before/after run of wrk -t2 -c20 -d30s https://your-site/ quantifies the gain. All four layers fit comfortably on a 1 GB VPS — Redis at 64–128 MB, the nginx cache on disk, and OPcache inside PHP’s own memory. If you are choosing hardware for a WordPress project, the VPS feature comparison at virtualserversvps.com highlights plans with enough RAM and fast storage for a caching stack, and the provider comparison helps you shortlist hosts with reliable NVMe tiers.

Start with OPcache and Redis today — they are the highest-impact, lowest-effort wins. Find a VPS sized for a full WordPress caching stack and launch your site.

Leave a Reply