LSCache serves finished pages straight from the web server — PHP and database stay out of the picture. For a blog that’s trivial: every page looks the same to every visitor. For a WooCommerce shop it’s not. Cart, checkout and customer account are different for every visitor, and a wrongly cached checkout is not a performance problem, it’s a privacy incident. This article shows how to set up the official LiteSpeed Cache plugin for WooCommerce so that product pages come from the cache and still nobody ever sees a stranger’s cart.
Prerequisite: WordPress with WooCommerce on our LiteSpeed Web Hosting. The plugin “LiteSpeed Cache” is installed and active. Basic activation takes two minutes — install the plugin, done; the rest of this article is fine-tuning.
Public cache and private cache — the difference in one minute
LSCache has two storage areas:
- Public cache: one copy per URL, served to all visitors. Perfect for product pages, categories and the front page.
- Private cache: one copy per visitor, tied to their session cookie. Only that one visitor gets to see it.
The rule for shops: everything that looks the same for everyone belongs in the public cache. Everything personalized — cart (/warenkorb/), checkout (/kasse/), my account (/mein-konto/) — must never end up in the public cache. The worst case is quickly explained: customer B sees customer A’s billing address and cart.
The good news: LSCache detects WooCommerce automatically and excludes these pages from the public cache on its own. We still wouldn’t trust that blindly — the typical reasons it goes wrong anyway are renamed page slugs (an English /cart/ instead of /warenkorb/, permalinks changed after the fact) or checkout plugins with their own URL. You can verify it in two minutes, see the verification section.
If your checkout runs under its own URL: LiteSpeed Cache → Cache → tab “Excludes” → “Do Not Cache URIs”, one URI per line:
/schnellkasse/
/mein-sonderbereich/
The WooCommerce base settings
Under LiteSpeed Cache → Cache, the “WooCommerce” tab appears automatically as soon as WooCommerce is active. Three settings matter:
- Product Update Interval: controls what gets kicked out of the cache on stock changes. The default (“purge product on changes to the quantity or stock status, purge categories only when stock status changes”) is the right choice in 95% of cases. Only if your category pages display stock levels should you pick the variant that also purges categories on every quantity change.
- Use Front Page TTL for the Shop Page: on — the shop overview then gets the same lifetime as the front page.
- Privately Cache Cart: may be on. The cart page then lands in the respective visitor’s private cache — speeds up repeat visits without a stranger’s cart ever showing up.
The mini cart: this is where ESI comes in
The mini cart in the header sits on every page — and shows something different per visitor. As soon as a visitor puts something in the cart, WooCommerce sets the cookie woocommerce_items_in_cart, and by default LSCache stops serving public cache copies to that visitor, because the counter would otherwise be wrong. The result without countermeasures: exactly the visitors who are close to buying browse your shop uncached — and therefore slowest.
The solution is called ESI (Edge Side Includes): the page still comes from the public cache but has “holes” that the web server fills per visitor from the private cache — the mini cart is such a hole. This works without contortions with us because the servers run LiteSpeed Enterprise, which means ESI support is complete.
Enable it under LiteSpeed Cache → Cache → tab “ESI”:
- Set “Enable ESI” to ON.
- Leave “Cache Admin Bar” and “Cache Comment Form” switched on — both are then delivered as private ESI blocks.
- If you use the classic mini cart as a widget: Appearance → Widgets → open the widget — an LSCache box is attached to it. Set “Enable ESI” to “Private”; the TTL can stay at the suggested values.
A note from the field: many current themes load the mini cart via AJAX anyway (visible in the network tab as ?wc-ajax=get_refreshed_fragments). Then the counter is correct even from the public cache, no ESI needed. Test first, configure second — if the cart counter in a private browser window counts up correctly after adding a product, you don’t have to touch ESI at all.
TTL for product pages
TTL (Time to Live) determines how long a cache copy stays valid. Set under LiteSpeed Cache → Cache → tab “TTL” → “Default Public Cache TTL”. The plugin default is 604800 seconds — one week.
That sounds risky for a shop, but it isn’t: price and stock changes purge the affected pages from the cache specifically (next section); the TTL is only the safety net behind that. For shops we still like to set 86400 seconds (1 day) — if a purge ever fails to land, the damage is limited to one day. The private TTL can stay at the default of 1800 seconds.
Purging on stock and price changes
In normal operation you don’t have to do anything: save a product with a new price and the plugin purges the product page automatically. If an order takes the stock level down, the “Product Update Interval” rule from above kicks in and purges product and, where applicable, category pages.
The typical pitfall is bulk changes that bypass WordPress: CSV imports, ERP integrations or direct database updates don’t always trigger the WordPress hooks — then the old copy stays visible until the TTL expires. So after every import, purge once completely: admin bar → LiteSpeed Cache → “Purge All”, or via SSH with WP-CLI (included in every plan):
wp litespeed-purge all
You can also append the command to the end of an import script or cron job.
Verification: is the cache actually running?
The proof sits in the response header x-litespeed-cache. Via SSH or from your own machine:
curl -sI https://dein-shop.de/produkt/beispiel/ | grep -i x-litespeed
First request: x-litespeed-cache: miss (page was freshly built and stored). Second request: hit — the cache is working.
Then the cross-check on the critical pages:
curl -sI https://dein-shop.de/kasse/ | grep -i x-litespeed
A hit must never appear here. If one does show up: check the excludes immediately (slugs, checkout plugin URLs, see above).
In the browser this works via F12 → network tab → reload the page → response headers of the first entry. Important: as a logged-in admin you’ll almost always see miss or no header at all — logged-in users get no public cache by default. Always use a private window for testing.
Pitfall: session cookies from third-party plugins
The most common reason a shop barely produces cache hits despite correct settings: a plugin starts a PHP session on every page. Classic candidates are currency switchers, booking and appointment plugins, or older wishlist plugins. The result: every response carries a Set-Cookie header, LSCache classifies the page as personalized, and the hit rate is in the basement — without a single error message.
Here’s how you find out:
curl -sI https://dein-shop.de/produkt/beispiel/ | grep -i set-cookie
A PHPSESSID on the very first anonymous request to a product page is the warning sign. (A wp_woocommerce_session_… cookie that only appears after a cart action is normal, by contrast.)
The fix, in this order: narrow down the culprit — deactivate plugins one after the other, ideally on a staging clone via the WordPress Toolkit in Plesk rather than on the live shop. Then look for an AJAX or “cache-compatible” mode in the culprit’s settings; many currency plugins have such an option. If there is none, it’s worth looking at an alternative. And if you get stuck: open a ticket at mein.xaweho.de/kontakt — we’ll look at the headers together.
Frequently asked questions
Do I additionally need WP Rocket, W3 Total Cache or the like? No — quite the opposite. Two page cache plugins know nothing of each other and don’t purge each other; that leads to exactly the stale pages you want to avoid. On LiteSpeed, the LSCache plugin is the right choice because it uses the cache inside the web server instead of a PHP workaround. Image optimization or CSS minify from other plugins you can keep — just switch off their page cache part.
Do logged-in customers get sped up too? Not via the public cache — that’s for anonymous visitors, and they make up the bulk of traffic in almost every shop. Logged-in users benefit from the private cache and ESI blocks, but the big lever remains the public cache for product and category pages.
A customer reports their cart shows wrong items — what now?
First “Purge All”, then use the curl tests from above to check whether /warenkorb/ and /kasse/ are really excluded from the cache. The classic cause behind it: page slugs that no longer match the excludes after a theme or language pack switch.
How often should I purge the cache completely? In normal operation: never. Product updates and orders purge automatically and specifically. Purge everything only after theme changes, plugin updates with frontend impact, and CSV imports. Anyone clicking “Purge All” daily is throwing away exactly the hits the cache is there for.
Which metric tells me whether all this paid off?
Time-to-first-byte (TTFB) of a product page, measured in a private window or via curl -w. Uncached, WooCommerce often sits at several hundred milliseconds depending on plugin load — from the cache, double-digit values are normal. Measure before, configure, measure after.
What’s next
- LiteSpeed Web Hosting — the product page. The flat fee is there too, in case we should move your entire shop.
- Choosing and setting the PHP version — the second performance lever next to the cache.
- WordPress Toolkit in Plesk — create a staging clone so plugin tests don’t happen on the live shop.
Setting up the LiteSpeed Cache plugin in WordPress
Install the LSCache plugin, set the basics, purge the cache and verify hits via the x-litespeed-cache header — step by step.
Plesk or LiteSpeed: which hosting for WordPress?
Both lines use Plesk and the WordPress Toolkit — the difference is the web server. When Plesk Web Hosting is enough and when LiteSpeed pays off.