Skip to content
xaweho

Knowledge base · intermediate

Setting up LSCache for WooCommerce properly

LiteSpeed Cache (LSCache) for WooCommerce: never cache the cart, ESI for the mini cart, TTL, purging on price and stock changes, verification.

intermediate ·

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”:

  1. Set “Enable ESI” to ON.
  2. Leave “Cache Admin Bar” and “Cache Comment Form” switched on — both are then delivered as private ESI blocks.
  3. 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

Related products
Tags
litespeed lscache woocommerce wordpress performance

Did this article help?

If not, open a ticket. If it did, we're happy about a referral — both sides get €25 credit on their customer account.