Repository navigation
LiteSpeed page cache
LiteSpeed page cache lets a LiteSpeed web server keep finished pages and hand them to visitors without running WordPress. SafeHouse only marks which responses the server may keep and tells it to drop them after changes. It writes no files and no .htaccess rules. Logged-in users, visitors with a cart, and the cart, checkout and account pages always get a page that WordPress builds for them.
The module is for sites on LiteSpeed Enterprise or OpenLiteSpeed that do not use the LiteSpeed Cache plugin. On other web servers its headers have no effect.
| Module ID | litespeed |
| Default | Off |
| Available | Unless the LiteSpeed Cache plugin is active. SafeHouse then shows "The LiteSpeed Cache plugin is active and manages the server cache itself." |
| WP-CLI |
wp shouse cache purge (only while the module runs) |
| Since | 0.1.0 |
LiteSpeed looks a page up in its cache before PHP runs. If the page is there, the visitor gets it and WordPress never starts. If it is not, WordPress builds the page, and SafeHouse's response headers tell the server whether to keep it and for how long.
SafeHouse decides in two steps. When WordPress starts to render a front-end page, the request can be cached only if all of these are true:
- the method is
GETorHEAD; - the visitor is not logged in;
- it is not wp-admin, an AJAX request, a preview, the Customizer or a search (
?s=); - the request carries no cookie whose name starts with
_lscache_vary,wordpress_logged_in_,wp-postpass_,comment_author_,woocommerce_items_in_cart,woocommerce_cart_hashorwp_woocommerce_session_; - the path does not start with a line of Never cache these paths.
When the page is complete, SafeHouse checks it again. The page is not cached when:
- the status is not 200, so 404 pages, errors and the 503 page of Maintenance mode are never cached;
- something defined
DONOTCACHEPAGEas true. WooCommerce does this for the cart, checkout and account pages. SafeHouse has no cart or checkout check of its own; - a cookie was set while the page was built;
- a
Cache-Controlheader containsno-cache,no-storeorprivate.
Requests that never render a front-end page get no cache header from SafeHouse. That covers the REST API (including the WooCommerce Store API), admin-ajax.php, wp-cron.php and wp-login.php. SafeHouse's own tests check that Store API answers are never served from the cache.
| Header | Sent when | Value |
|---|---|---|
X-LiteSpeed-Cache-Control |
The page may be cached |
public,max-age= followed by Keep pages for (minutes) in seconds, by default public,max-age=14400
|
X-LiteSpeed-Tag |
The page may be cached | shouse |
X-LiteSpeed-Cache-Control |
A front-end page that may not be cached | no-cache |
X-LiteSpeed-Purge |
After a change | tag=shouse |
LiteSpeed adds its own X-LiteSpeed-Cache header to its answers, with hit when the page came from its cache. That is the header to look for when you check the cache.
LiteSpeed does not recognize WordPress's login cookie or WooCommerce's cart cookies, so on its own it would give a logged-in user the page cached for anonymous visitors. It does keep a separate cache for visitors who carry a _lscache_vary cookie. SafeHouse sets that cookie for every visitor whose pages are personal, and never lets their pages be cached, so they always reach WordPress.
| Name | _lscache_vary |
| Value | 1 |
| Flags |
HttpOnly, SameSite=Lax, Secure on HTTPS |
| Path and domain |
COOKIEPATH (or /) and COOKIE_DOMAIN
|
SafeHouse sets the cookie:
- at login, until the login expires;
- when someone leaves a comment, for as long as WordPress keeps the commenter's cookies (30,000,000 seconds, about 347 days, unless a plugin changes the
comment_cookie_lifetimefilter); - when WooCommerce sets its cart cookies, for 2 days;
- for a logged-in user who has no vary cookie yet (for example, someone who logged in before the module was on), for 2 days.
It removes the cookie at logout, and when WooCommerce clears its cart cookies for a visitor who is not logged in.
Every purge clears every page SafeHouse marked. The header is always X-LiteSpeed-Purge: tag=shouse, never a single address, even when only one post changed.
SafeHouse purges after:
- publishing a post, page or other public post type, or saving one that is already published;
- unpublishing, trashing or deleting a published post;
- a comment that is approved, and any change to a comment's status or text;
- a WooCommerce stock or stock status change;
- switching the theme, saving the Customizer, saving a menu or changing widgets;
- installing or updating WordPress, a plugin or a theme through the WordPress updater, and activating or deactivating a plugin;
- any save of SafeHouse settings, including
wp shouse module enableandwp shouse module disablefor any module. Switching this module off this way also clears the pages it marked; - another plugin firing the
litespeed_purge_allaction. Maintenance mode does this when it is switched on or off; -
Clear the cache and
wp shouse cache purge.
Nothing else purges. Pages also expire on their own after Keep pages for (minutes).
The purge header has to travel in a response. In a web request, such as saving a post in wp-admin, it goes out with that response and the server clears the pages at once.
When there is no response to carry it, SafeHouse stores the purge in the option shouse_litespeed_purge and sends it with the next request that WordPress handles. This happens:
- for every change made in WP-CLI, for example
wp post update; - for changes made after the response was already sent, as WordPress cron does.
A page served from the LiteSpeed cache does not start WordPress, and wp-cron.php answers before WordPress loads, so neither sends a stored purge. Until some request reaches WordPress (someone opens wp-admin, a logged-in user browses, or a visitor opens a page that is not cached), visitors can still get the old pages.
wp shouse cache purge also requests admin-ajax.php once in the background, so the purge applies at once. Other WP-CLI commands do not. After changing content with WP-CLI, run wp shouse cache purge or open any wp-admin page.
On SafeHouse → Modules → LiteSpeed page cache, select Details.
| Setting | Default | What it does |
|---|---|---|
| Keep pages for (minutes) | 240 | From 5 to 480. "At most 8 hours, so forms on cached pages still carry a valid security token. Changes clear the cache anyway." |
| Never cache these paths | Empty | "One per line, for example /contact/. A line matches every address that starts with it." Only the path is compared, without the query string, and the match is case-sensitive. Up to 2000 characters in total. |
While the module runs, Details also shows a line about the server and the Clear the cache button. The line reads "This server is LiteSpeed. Tools → Site Health checks whether it actually serves pages from its cache." or, on other servers, "This server does not look like LiteSpeed, so the cache headers have no effect here."
SafeHouse cannot turn the server cache on. The server or your host does.
On LiteSpeed Enterprise, add this to the site's .htaccess, or ask your host to turn the cache on:
<IfModule LiteSpeed>
CacheLookup public on
</IfModule>On OpenLiteSpeed, the cache is part of the server configuration. Its cache module must be on and must store the pages PHP marks public. SafeHouse's own test server runs OpenLiteSpeed with the cache module set to checkPublicCache 1 and enableCache 0: it looks up public pages and caches only what PHP marks. If you do not manage the server, ask your host.
Then switch the module on:
- Go to SafeHouse → Modules → LiteSpeed page cache.
- Turn on the switch.
- Select Save Changes.
Tools → Site Health runs the test "SafeHouse LiteSpeed page cache". It loads the home page twice without cookies and reads LiteSpeed's cache header on the second answer.
| Result | Status | Text |
|---|---|---|
| "LiteSpeed serves pages from its cache" | Good | "The home page came from the LiteSpeed cache for a visitor who is not logged in." |
| "LiteSpeed does not serve pages from its cache yet" | Recommended | "The server is LiteSpeed, but the home page was not served from its cache. On LiteSpeed Enterprise add this to .htaccess, or ask your host to turn the cache on: CacheLookup public on . A page that sets a cookie for every visitor is never cached either." |
| "The server is not LiteSpeed" | Recommended | "The LiteSpeed page cache module has no effect on this server. Switch it off, or use the cache your host provides." |
The test does not follow redirects. If the home page address redirects, for example from http:// to https:// or to www, the test sees only the redirect. Check that Settings → General → Site Address (URL) is the address visitors end up on.
To see a page the way visitors do, test in a private browser window. A browser you are logged in with carries the vary cookie, so it never gets cached pages. The same holds for a browser that has left a comment or has something in the cart.
- Open a private window.
- Open the browser's developer tools on the Network tab.
- Load the same page twice.
- Select the page request and look for
X-LiteSpeed-Cache: hitin the response headers.
From a terminal, run this twice. The second run prints x-litespeed-cache: hit when the page came from the cache:
curl -s -o /dev/null -D - https://example.com/ | grep -i x-litespeed-cacheIf a page is never a hit:
- the server cache is off (see Set up the cache);
- a plugin sets a cookie on every page, as some consent banners and language switchers do;
- a plugin sends
Cache-Controlwithno-cache,no-storeorprivate, or definesDONOTCACHEPAGE; - the path matches a line of Never cache these paths;
- the page does not answer with status 200.
In wp-admin:
-
Go to SafeHouse → Modules → LiteSpeed page cache and select Details.
-
Select Clear the cache.
SafeHouse shows "LiteSpeed was asked to clear the cache." and writes the action to the activity log.
With WP-CLI:
wp shouse cache purgeThe command prints Success: Purge queued; LiteSpeed applies it with the next request to the site.
While WooCommerce geolocates customers without page caching support, the Site Health result is Recommended even when the cache works, and its text ends with:
WooCommerce geolocates customers without page caching support, so cached pages may show one country's prices and taxes to everyone. In WooCommerce → Settings → General choose "Geolocate (with page caching support)".
To fix it:
- Go to WooCommerce → Settings → General.
- Choose Geolocate (with page caching support).
- Save the WooCommerce settings.
- While the LiteSpeed Cache plugin is active, this module is Unavailable and does not run. The plugin manages the server cache instead. Set
SHOUSE_IGNORE_OVERLAPStotrueto run both. - Maintenance mode clears the cache when it is switched on or off, and its 503 page is never cached.
- Cloudflare cache reacts to the same changes. Both modules can run together.
- Option
shouse_litespeed_purge(not autoloaded): a stored purge waiting for the next request. It is deleted once sent. - Cookie
_lscache_varyin the browsers of logged-in users, commenters and visitors with a cart. - Activity log entries
cache_purged: "LiteSpeed cache cleared from the settings page" or "LiteSpeed cache cleared from WP-CLI". Automatic purges are not logged.
The cached pages themselves live in the server's cache, not in WordPress. Uninstalling SafeHouse deletes the option. Vary cookies stay in browsers until they expire.
- Every purge empties all of the site's cached pages, even for a one-word edit.
- SafeHouse does not look at query strings, except for searches (
?s=). Addresses with a query string are cacheable like any other, and Never cache these paths cannot exclude a query string. - A page that shows personal content without a cookie,
DONOTCACHEPAGEor aCache-Control: privateheader can be cached and shown to everyone. Add its path to Never cache these paths. - Changes made with WP-CLI or after a response wait for the next request that reaches WordPress.
- Changes outside the list in Purges do not purge, for example editing a category name, changing an option other than the ones listed, or editing a user. Pages update when they expire.
- WooCommerce can save a price change without updating the product post, for example through its REST API or when a scheduled sale starts. Such a change may not purge. If you rely on it, test it on a staging site; until then Keep pages for (minutes) limits how long an old price can show.
- The module only sends headers. It does not warm the cache and does not optimize images, CSS or JavaScript.
These pages describe SafeHouse 0.2.0 and were last reviewed on 2026-10-07. · Repository · Releases · Changelog · Report a problem with these pages
Search every page and heading in the Pages box.
Start here
Modules
- All modules
- Security: Hardening · Login limits · Bot protection · Install lockdown
- Alerts: Change alerts · Plugin health · Vulnerability alerts
- Performance: LiteSpeed page cache · Cloudflare cache · Redis object cache
- WooCommerce: Omnibus price history
- Site tools: SMTP mail · Header and footer scripts · Duplicate posts and pages · Maintenance mode · Tweaks
Guides
- Behind Cloudflare or a proxy
- Running with Wordfence
- Configure in wp-config
- Deploy with git or CI
- Replacing other plugins
- Upgrade from WPHouse
Reference
Trust
Help