All posts

Nginx FastCGI cache vs LiteSpeed cache: same theme, same pages

WordPress 7.1.4 + Twenty Twenty-Five: Nginx fastcgi_cache hit 0.22 ms vs OpenLiteSpeed LSCache hit 0.33 ms. Miss TTFB, headers, and both configs.

Written by NodeRings Inc.

NodeRings Inc. writes these notes. The company runs the marketplace and the agent that stays on the provider’s side of the hypervisor.

Same WordPress 7.1.4, same active theme (Twenty Twenty-Five 1.5), same anonymous homepage path. On Nginx 1.24.0 with fastcgi_cache, a warm hit answered in 0.22 ms median TTFB (X-FastCGI-Cache: HIT). On OpenLiteSpeed with LiteSpeed Cache 7.9.3, a warm hit answered in 0.33 ms (x-litespeed-cache: hit). Misses stayed in the tens of milliseconds on both stacks: Nginx miss median 32.99 ms on the lab host, OLS uncached median 50.89 ms on a 2 GiB guest. Hits skip PHP either way.

Miss milliseconds sit on different hardware: Nginx on the lab host, OLS inside the CyberPanel guest from the OLS + LSCache TTFB lab. The fair claim is narrower. With the same theme and page class, both page caches put anonymous HTML under a millisecond on loopback once warm. Pick the stack you already operate.

Nginx FastCGI cacheOpenLiteSpeed + LSCache
WordPress7.1.47.1.4
ThemeTwenty Twenty-Five 1.5Twenty Twenty-Five 1.5
Miss / uncached median TTFB32.99 ms (MISS)50.89 ms (plugin off)
Hit median TTFB0.22 ms0.33 ms
Hit p950.31 ms0.40 ms
Samples (hit)2020
Cache headerX-FastCGI-Cache: HITx-litespeed-cache: hit
Where measuredlab host loopback2 GiB guest loopback
Bar chart. Nginx miss 33 ms hit 0.22 ms; OLS miss 50.9 ms hit 0.33 ms.
Same WP and theme. Miss hosts differ; both hits are sub-millisecond page-cache answers.

Page cache versus object cache

fastcgi_cache and LSCache (public page cache) store the finished HTML for anonymous GET requests. A hit never starts PHP-FPM or lsphp for that URL. Redis/Valkey object cache is a different layer: PHP still runs, MariaDB work shrinks. You can run page cache and object cache together.

Logged-in cookies, carts, and wp-admin must bypass the public page cache. Both setups above do that.

Nginx FastCGI cache

# http {
fastcgi_cache_path /var/cache/nginx/wp_fcgi levels=1:2
    keys_zone=wp_fcgi:32m max_size=256m inactive=60m use_temp_path=off;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

map $http_cookie $skip_cache_cookie {
    default 0;
    ~*wordpress_logged_in_ 1;
    ~*comment_author_ 1;
    ~*wp-postpass_ 1;
}
# }
# server — location ~ \.php$
fastcgi_pass unix:/run/php/php8.3-fpm-wp.sock;
fastcgi_cache wp_fcgi;
fastcgi_cache_valid 200 301 302 60m;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
add_header X-FastCGI-Cache $upstream_cache_status;

Set $skip_cache from method, cookie map, and /wp-admin/ URI checks. Then:

curl -sI -H 'Host: wp-fpm.lab' http://127.0.0.1/ | grep -i fastcgi
# X-FastCGI-Cache: HIT   (after a warm request)

curl -s -o /dev/null -w '%{time_starttransfer}\n' \
  -H 'Host: wp-fpm.lab' http://127.0.0.1/

This lab’s miss median was 32.99 ms after purge (10 samples). Hit median was 0.22 ms (20 samples). The site was the PHP-FPM pool WordPress on the host LEMP stack.

Terminal freeze of fastcgi_cache_path, cache key, and PHP location cache directives.
Zone in http{}, cache on the PHP location, status header from $upstream_cache_status.
Terminal freeze of Nginx miss 32.99 ms and hit 0.22 ms with X-FastCGI-Cache headers.
Purge the cache directory for a clean miss, then warm and sample hits.

OpenLiteSpeed + LSCache

On the CyberPanel OLS guest, LiteSpeed Cache 7.9.3 was active with public cache on. After emptying object files under the vhost cache data dir (leave .cacheman*), the first request showed x-litespeed-cache: miss at 57.99 ms. Twenty warm hits: median 0.33 ms, p95 0.40 ms, header hit. With the plugin deactivated, median TTFB was 50.89 ms.

# on the OLS host
wp plugin activate litespeed-cache
wp litespeed-option set cache 1

curl -sI -H 'Host: wp-ols.lab' http://127.0.0.1/ | grep -i litespeed
# x-litespeed-cache: hit

Full install and header walkthrough: OpenLiteSpeed and LSCache TTFB.

Terminal freeze of OLS miss then hit 0.33 ms with x-litespeed-cache hit.
Same theme and WP major as the Nginx side. Hit header is x-litespeed-cache: hit.
Terminal freeze showing WordPress 7.1.4 and Twenty Twenty-Five 1.5 on both stacks.
Theme and core versions matched for the comparison.

How the stacks differ in ops

Nginx FastCGI is config in files: purge by deleting files under the cache path or using a helper module, no WordPress UI unless you add a plugin. LSCache ships a WP plugin with purge-on-publish, ESI options, and a CyberPanel/OLS path that already expects it.

QUIC/HTTP3 and OLS-specific features are outside this loopback HTTP/1.1 test. On the numbers that matter for anonymous HTML, both hits are “PHP is out of the way.”

Terminal freeze of X-FastCGI-Cache HIT and x-litespeed-cache hit headers.
Read the cache header before you quote a hit TTFB. Logged-in cookies must bypass.

Skip these

Skip thisWhat to do
Comparing one stack’s hit to the other’s missQuote miss and hit for each, with headers
Measuring through a CDNOrigin loopback first
Logged-in or cart cookies in the “hit” sampleAnonymous client only
Calling object cache a page-cache winDifferent layer
Treating host vs guest miss ms as a product rankingSame hardware if you need a miss race

Where this fits on a VPS

A marketplace Compute Instance at 2 GB runs either LEMP + FastCGI cache or OLS/CyberPanel + LSCache. If you already live in Nginx, add fastcgi_cache. If you already run CyberPanel, turn on LSCache and confirm x-litespeed-cache: hit. Size PHP workers for the misses that remain (pool sizing).

What broader benches say about the same fight

Cached WordPress homepage benches that pair OpenLiteSpeed or LiteSpeed with LSCache against Nginx with FastCGI cache usually put the LiteSpeed family ahead on requests per second and warm TTFB when PHP never runs. Uncached dynamic PHP often flips or narrows the gap toward Nginx + PHP-FPM. FastCGI cache is application-agnostic and easy to mis-purge; LSCache’s WordPress plugin owns cookie varies and WooCommerce hooks at the cost of living inside that plugin. Use this lab’s same-theme timings as the number for this guest, and treat vendor “12×” claims as upper bounds on their hardware.

FAQ

Which is faster? On this theme and URL, both hits are under half a millisecond on loopback. The gap is noise next to WAN RTT.

Do I need both? No. One page cache for anonymous HTML is enough. Add object cache if logged-in or dynamic PHP is the pain.

Purge on publish? LSCache does this in-plugin. On Nginx, wire a purge hook or clear the cache path from deploy.

HTTP/3? Not in this lab. Enable it on the edge you already trust; re-measure there.

Anonymous page cache is the same job on both sides: store HTML, serve it, skip PHP. Match theme and headers, then choose Nginx or OLS for the rest of your ops. Let WAN RTT and purge workflow decide, not a tenth of a millisecond on loopback.