Skip to content

Full-page cache

P2Lab Cache replaces Shopware’s default HTTP cache store and serves complete HTML responses for cacheable storefront routes. Once a page is in cache, the next visitor receives it without touching the templating engine, database or framework boot — only the HTTP layer.

Each storefront response is classified into one of these cache types:

TypeWhat it covers
productProduct detail pages (frontend.detail.page)
categoryCategory landing pages (frontend.navigation.page)
listingAJAX listings + filter responses (frontend.navigation.page.ajax, frontend.navigation.filter)
cmsCMS pages and home page (frontend.home.page, frontend.cms.page)
buyboxAsync buybox responses (off by default)

Toggle each type independently from Settings → Speed Boost → Dashboard → Cacheable Routes.

P2Lab Cache follows the same rules as Shopware’s stock HTTP cache for skipping:

  • Logged-in customers (session cookie + customer context)
  • Carts with at least one line item
  • POST / PUT / DELETE — only GET responses are cached
  • Responses with Cache-Control: no-store or private
  • Responses that set sensitive cookies
  • Requests with un-ignored query parameters

The plugin adds one more knob: Ignored Query Parameters (see Query parameter filtering). Any parameter listed there is stripped from the cache key — so ?utm_source=newsletter and the bare URL share the same entry.

For every cacheable GET request:

  1. Compute the cache key — URL + sales channel + currency + theme + cleaned query string.
  2. Lookup in backend — Filesystem, Redis or APCu (whichever is configured).
  3. If found and not expired → serve from cache (HIT). Send Cache-Control headers and, if debug mode is on, the X-P2Lab-Cache-* headers.
  4. If not found → let Shopware render the response, capture it, store it under the cache key with the right TTL and tag set, then return it (MISS).

Each cache entry stores:

  • The full HTTP response body (optionally gzip-compressed)
  • The response headers Shopware sets
  • The cache tag set computed for that response — used later for invalidation
  • Metadata used by the dashboard: original size, cached size, generation time, cache-hit time, type

Metadata for every entry is also persisted in the database (p2lab_cache_entry) so the dashboard can report numbers regardless of which backend you picked.

Three settings control how long an entry lives:

  • Cache TTL (default: 1 day) — server-side TTL. The entry is evicted from the backend after this time.
  • max-age (default: 0)Cache-Control: max-age=… sent to the browser. 0 means the browser must re-validate every time (the cache still serves the response fast).
  • s-maxage (default: 6 hours)Cache-Control: s-maxage=… sent to shared caches between you and the browser.

See Cache-Control headers for how the three combine.

When Enable Cache Compression is on (default), the stored payload is gzip-compressed at the chosen level. The HTTP response body sent to the client is not compressed by this setting — that is handled separately by the web server.

Typical savings:

LevelRatioCPU cost
1~30%very low
3~40%low
6~50%balanced (recommended)
9~55%highest

See Compression for tuning notes.

The dashboard has a Clear all button plus per-type clears (Products / Categories / Listings / CMS / Buybox). Use these instead of clearing the whole Symfony cache when you only want to drop a slice — for example after a CMS-only deployment.

For every entry, the plugin records:

  • count per type
  • total cached size vs total original sizetotal space saved
  • average generation time (MISS render)
  • average cache-hit time (HIT serve)

The dashboard refreshes these in real-time during warmups. See Admin dashboard.