With Shopware 6.7.6.0, released on 13 January 2026 (Shopware Release Notes 6.7.6.0), the storefront gets its most consequential performance change in years: the cache rework makes the HTTP cache work even when customers are logged in or have items in the cart. The enabler is the new sw-cache-hash, which bundles login state, tax state, currency and customer group into a single context key. This article explains the concept, delayed invalidation, the breaking changes for custom extensions and a realistic rollout plan for your Shopware store.

Why the full-page cache used to stop at login

The classic storefront renders every page server-side with Twig. In front of it sits the HTTP cache as a full-page cache: it stores the finished HTML response and serves it on the next request without PHP, database and search index doing the work again. Until now, two cookies told that layer a response was no longer generic: sw-states with the states logged-in and cart-filled, plus sw-currency for the selected currency. As soon as one of those states appeared, the request bypassed the full-page cache. Both mechanisms are deprecated with the cache rework and lose their effect in the next major release (Shopware Release Notes 6.7.6.0).

Commercially, that hits exactly the wrong spot. Without a full-page cache, the pages that run unbuffered through the application are the ones where people with purchase intent are browsing: the category page after login, the product detail page with a customer group price, the catalogue view with a filled cart. Shopware quantifies the difference between uncached and cached delivery as 500 milliseconds versus 50 milliseconds (Shopware News), roughly a tenfold gap. How much those fractions of a second matter is shown by the joint Deloitte and Google study across 37 brands: improving mobile site speed by 0.1 seconds lifted retail conversions by 8.4 % and average order value by 9.2 % (Deloitte).

Scope: Store API caching is a separate topic

This article covers the classic storefront and delivery to logged-in customers only. The caching layer for headless frontends - GET instead of POST on Store API routes, cache-control headers in the frontend, stale-while-revalidate and backend-for-frontend patterns - is described in a dedicated article: Store API caching for headless shops. Both layers come from the same rework, but they concern different architectures and different teams.

Situation in the shopPreviouslyWith cache rework
Guest without cartFull-page cache activeFull-page cache active
Customer logged inCache disabledCache active, hash per context
Cart filledCache disabledCache active, cart via Ajax
Foreign currencySeparate sw-currency cookiePart of sw-cache-hash
Customer group priceNo full-page cacheDedicated cache entry
InvalidationImmediate on every changeCollected in intervals

The second reason for the rebuild is key explosion. Previously, every matching Rule Builder rule fed into the cache calculation. Shopware illustrates that 50 active rules combined with language, currency and tax states produce 1,125,899,906,842,624 possible combinations (Shopware News). A cache that would have to hold that many variants no longer reaches a usable hit rate - practically every request becomes a miss. Anyone maintaining many pricing rules and promotions in the Rule Builder knows the effect from monitoring: high load despite a supposedly active cache.

sw-cache-hash: context becomes the cache key

The heart of the rework is a single value. The sw-cache-hash contains the hash of all cache-relevant information of a session and is set both as a cookie and as an HTTP header; Shopware additionally adds the header name to the Vary header of the response (Shopware Developer Documentation). That way every standards-compliant cache - the Symfony cache as well as an upstream reverse proxy - understands that the same URL can have different responses depending on context.

  • Login state: whether a customer is signed in
  • Tax state: gross or net display, decisive in B2B
  • Currency: replaces the former sw-currency cookie
  • Customer group: different prices and visibilities
  • Cache-relevant rules: by default only rules from the product area, while checkout-related rules such as payment methods or promotions are deliberately excluded (Shopware Developer Documentation)

One small, often overlooked rule decides the hit rate: the cookie is only set once the state differs from the default. That default is defined as no logged-in customer, default currency, empty cart (Shopware Developer Documentation). Anonymous visitors therefore keep sharing one common cache entry - by far the largest share of traffic in most shops stays as cheap as before. Only signing in, switching currency or adding an item creates a dedicated hash and with it a dedicated cache variant.

Response of a storefront page
HTTP/1.1 200 OK
cache-control: public, s-maxage=3600, stale-while-revalidate=60
vary: sw-cache-hash
sw-cache-hash: 9f2c41ab7d3e
set-cookie: sw-cache-hash=9f2c41ab7d3e; path=/; secure; samesite=lax

<!doctype html> ...

In parallel, the cache key itself is drastically slimmed down. The rework proposal states that it should only contain five context values: sales channel ID, language ID, currency ID, tax state and customer group ID (shopware/shopware GitHub Discussion #3299). Billions of theoretical permutations turn into a manageable, predictable set of variants. At the same time many former object caches of the Store API layer move into the HTTP cache; what remains in the object cache is mainly data needed by practically every request, such as the base sales channel context (shopware/shopware GitHub Discussion #3299).

What this means in practice

Instead of "logged in means no cache", the rule becomes "logged in means a different cache entry". A shop with three customer groups, two tax states and two currencies produces a two-digit number of variants - an order of magnitude any reverse proxy handles comfortably. Warm-up works per variant: the first request fills the entry, every further user of the same customer group benefits from it.

Delayed invalidation: higher hit rates, new expectations for editorial work

The second major change concerns emptying rather than filling the cache. Since Shopware 6.7, delayed invalidation is the default: changes no longer discard affected entries immediately but are collected and processed at regular intervals. The default interval is 5 minutes and can be adjusted via the run interval of the shopware.invalidate_cache scheduled task (Shopware Developer Documentation). The former configuration option for the delay has been removed because the behaviour is active anyway.

The gain is substantial. Importing 400 products used to trigger 400 individual invalidation waves; each one tore category pages, listings and navigation fragments out of the cache and forced expensive recalculations. Collected invalidation merges those events, removes duplicates and runs them in one pass. The result is a noticeably higher hit rate and calmer system load during imports - in our experience the difference between a shop that struggles during the nightly import and one that barely notices it (project experience). In addition, list-type routes are not tagged with all returned entities but deliberately rely on a TTL, because full tagging would be too expensive (Shopware Developer Documentation).

A new expectation inside the team

Price, stock and text changes no longer appear instantly in the storefront after saving, but typically within the configured interval. That is not a bug, it is the intended behaviour. Editorial staff, purchasing and customer service should know this before the first "the price in the shop is wrong" ticket arrives.

  • Price maintenance: making corrections visible now means waiting for the interval or purging deliberately
  • Campaign launches: plan landing pages and start times with a buffer instead of timing them to the second
  • Stock display: deliver scarce stock levels through client-side fragments when minute-level accuracy matters
  • Discount campaigns: choose end times so that one interval remains as a buffer
  • Approval processes: admin preview and live state can diverge temporarily - that belongs in the working instructions

Technically the reliability of the interval depends directly on background processing. If the scheduled task worker is not running continuously, collected invalidations pile up and outdated content stays visible longer than planned. A properly monitored worker setup is therefore no longer optional but a prerequisite for correct cache behaviour; the operational side of scheduled processing is part of our guide to Shopware performance optimisation.

A cache that is fully emptied on every minor change is not a cache, it is a queue in front of the database.

XICTRON development team

Breaking change: extensions must work with the cache enabled

For merchants this is the most important part of the whole rework. Until now, plugins and themes could rely on the full-page cache being inactive for logged-in customers - customer-specific content could safely be rendered straight into the template. That assumption is gone. The constants CacheStateSubscriber::STATE_LOGGED_IN and CacheStateSubscriber::STATE_CART_FILLED are deprecated and no longer used; extensions have to be reworked so that they behave correctly with caching enabled for logged-in customers and filled carts (Shopware Release Notes 6.7.6.0).

The failure mode is uncomfortably concrete: if an extension renders the name of the signed-in person, individual wish lists, open quotes or loyalty points directly into the cached page, that data ends up in the shared cache entry of the respective variant. The next user with the same hash then sees foreign or outdated states. Anyone running custom extensions or who has just completed a plugin migration to Shopware 6.7 should check this point before enabling the flag, not after.

Personal fragments

Greeting by name, customer number, recent orders or wish lists do not belong in cached HTML but in lazily loaded fragments or ESI blocks.

Customer group prices

Prices, tiers and availabilities must be covered by the context hash. Whatever does not feed into the hash must not change the rendered page.

Cart widgets

Cart counters, mini cart and subtotals run through separate, uncached calls. Rendering them directly in the header produces wrong numbers for other users.

B2B net view

Tax state is part of the hash. Custom switches between net and gross have to set that state cleanly, otherwise views get mixed.

Rule-driven content

Blocks reacting to rules need a cache-relevant rule or client-side loading. Checkout-related rules are deliberately kept out of the hash.

Cache control per route

Custom controllers should set their cache policy explicitly instead of relying on global defaults that are being removed.

Instead of hard-wired code, Shopware provides configurable caching policies. They allow defaults per area, a distinction by use case and overrides at route level (Shopware Developer Documentation). This makes it possible to control precisely which page is cached publicly for how long and which one stays private.

config/packages/shopware.yaml
shopware:
  http_cache:
    policies:
      catalogue_long:
        headers:
          cache_control:
            public: true
            max_age: 600
            s_maxage: 3600
            stale_while_revalidate: 60
      account_private:
        headers:
          cache_control:
            private: true
            no_store: true

At the same time familiar knobs lose their effect: the environment variable SHOPWARE_HTTP_DEFAULT_TTL and the parameter shopware.http.cache.default_ttl are ineffective with the rework active and scheduled for removal in 6.8.0.0 (Shopware Release Notes 6.7.6.0). If your configuration still maintains those values, replace them with policies instead of assuming they keep working quietly. For troubleshooting, a log of tag invalidations can additionally be switched on from 6.7.7.0 via tag_invalidation_log_enabled, which is disabled by default (Shopware Developer Documentation).

Test checklist for staging

The decisive question before rollout is not "will the shop be faster?" but "does every user still see what they are supposed to see?". That check belongs in staging with the CACHE_REWORK flag enabled, production-like data and an upstream reverse proxy - only there does it become visible whether variants are separated cleanly. The following checklist has proven itself in projects and covers the places where mixing typically occurs (project experience).

  • Two accounts in parallel: two separate browser profiles, two customers from different customer groups, the same URLs in alternating order
  • Guest afterwards: after both sessions check the same pages in a private window - no name, no wish list and no special price may show up
  • Cart states: empty, one item, many items, item removed - verify cart counter and mini cart in every state
  • Customer group prices: compare the same product in a trade and an end-customer group, including tier prices and struck-through reference prices
  • B2B net view: switch between net and gross, then return to previously visited pages
  • Currency switch: choose a foreign currency, browse the catalogue, switch back and check prices again
  • Language switch: the same page in all active languages, especially on shared domains
  • Rule-driven blocks: check content tied to rules, such as shipping notices or campaign banners
  • Login and logout: sign out, reload the same page, then sign in with a different account
  • Customer-specific visibilities: hidden categories or blocked products per customer group
  • Forms and tokens: submit contact form, review form and other pages with CSRF protection
  • Editorial flow: change a price in the admin, note the time and measure visibility in the storefront against the invalidation interval

The two-account test is the single most effective step. Create two test customers that differ in customer group and tax state, then work through a fixed list of twenty to thirty URLs: home page, three categories, five products, a search result, wish list, account overview. Afterwards run the same list in reversed order and finally as a guest. Any deviation that can only be explained by the order is a cache defect, not a coincidence. Shops with pronounced price structures should also review their B2B requirements for prices and visibilities.

Automate instead of clicking

A simple script run that requests the URL list with two different sw-cache-hash cookies and diffs the responses finds mixing more reliably than manual testing. Prices, salutation and cart counter work well as markers in the diff.

Interplay with reverse proxy and edge layers

One key goal of the rework was to simplify reverse proxy configuration. Instead of several Shopware-specific headers and complex special logic, the sw-cache-hash as header and cookie is enough: the proxy uses that value as part of its cache key and can differentiate entries for the same URL by application state (Shopware Developer Documentation). Because the value is announced in the Vary header, the mechanism works in principle with any standards-compliant cache.

LayerWhat is cached hereInvalidation
BrowserStatic assets, private responsesVia max-age and versioning
CDN or edgePublic HTML responses per hash, images, CSS and JSPurge calls and s-maxage
Reverse proxyStorefront responses per sw-cache-hashTag or URL based, in intervals
Shopware HTTP cacheRendered pages in the application cacheCollected via the scheduled task
Object cacheOnly base data such as sales channel contextTag based

For globally delivered shops the same logic applies one level higher: edge nodes can separate variants by hash as well, provided the header is passed through consistently. How that combines with geographically distributed locations is described in our article on edge caching for Shopware. What stays essential is a clean alignment with the server environment: planning proxy, workers and storage separately only moves the bottleneck, which is why the topic belongs in hosting and operations planning.

Preventing cache poisoning: validate the context hash server-side

As soon as personalised responses live in a shared cache, the integrity of the context key becomes a security matter. A publicly documented finding in Shopware's tracker describes exactly that: if a signed-in person deletes the cookies sw-states and sw-cache-hash and then requests a cacheable page, the application renders the page with that person's session data - and stores it as a generic entry for lack of a marker. The cause was that key generation trusted the cookies of the request instead of the values set by the server in the response (shopware/shopware GitHub Issue #12756).

The countermeasure is conceptually simple and decisive in practice: the server calculates the context hash itself, compares it with the value supplied and uses the corrected, server-side value for the cache key. Client-supplied values are a hint, not a truth. For merchants this mainly means keeping patch levels current and configuring the proxy layer so that it does not undermine that assumption.

  • Keep patch levels current: security-relevant fixes to cache key generation belong to the updates that should be applied promptly
  • Normalise cookies: the proxy should discard unknown or manipulated cookie values instead of feeding them into the key
  • Check set-cookie in public responses: responses that set session cookies must not be marked as publicly cacheable
  • Monitor account-independent markers: automated checks for salutation or customer number in the HTML detect mixing early
  • Treat the Store API separately: headless setups need their own safeguards, which build on the fundamentals in IT security for e-commerce
No cache rework without a security review

A full-page cache for logged-in customers is a performance win and a new attack surface at the same time. Before enabling it, check that your proxy rules, your cookie handling and your extensions fit together. A carefully planned staging test is considerably cheaper than an incident in production.

Scope: object cache, CDN and Store API

In discussions, four caching layers get mixed up regularly. They solve different problems and cannot substitute for one another:

Storefront HTTP cache

Stores finished HTML responses per context hash. That is the subject of this article and the biggest lever for time to first byte.

Object cache

Stores intermediate results of the application. The rework shrinks its role but it stays relevant for base data - details in our article on Redis caching for Shopware.

CDN and edge

Brings assets and public responses closer to users. It complements the HTTP cache rather than replacing it - fundamentals in our CDN strategy for online shops.

The fourth layer is the Store API. It serves data to decoupled frontends and follows its own logic with GET routes, dedicated cache-control headers and stale-while-revalidate. If your shop runs a headless frontend, the article on caching the Store API layer is the right entry point; for the classic Twig storefront the full-page cache described here remains decisive. If you operate both, plan both layers separately and measure them separately.

Rollout plan: enable the flag in staging and prove the effect

The rework can be introduced in a controlled way. The feature flag CACHE_REWORK enables the cache-related changes only; alternatively PERFORMANCE_TWEAKS covers all performance-related changes and v6.8.0.0 all upcoming breaking changes (Shopware Release Notes 6.7.6.0). For a production shop the narrow switch is the right choice: it limits the amount of change and keeps causes traceable when something deviates.

  1. Inventory: review extensions, themes and custom controllers for personalised output and custom cache logic
  2. Baseline measurement: record hit rate, time to first byte and origin requests over at least one full week, including load peaks
  3. Enable staging: set CACHE_REWORK in staging, clear caches, configure the reverse proxy identically to production
  4. Work through the checklist: two-account test, cart states, customer group prices and B2B net view as described above
  5. Comparative measurement: collect the same metrics again and document the difference instead of estimating it
  6. Roll out in a controlled way: enable during a quiet window, then watch error rates, order completions and support requests closely
Terminal
$ bin/console feature:list
CACHE_REWORK ... inactive
$ SHOPWARE_FEATURE_CACHE_REWORK=1 bin/console cache:clear
$ bin/console scheduled-task:run
shopware.invalidate_cache scheduled

Three metrics matter. First the hit rate of the cache, split by anonymous and signed-in requests - this is where the actual effect of the rework becomes visible. Second time to first byte: 0.8 seconds or less counts as good, measured at the 75th percentile of users (web.dev). Third the requests reaching the origin, meaning the load that still gets through to the application. All three belong in continuous monitoring of uptime and performance so that regressions after future updates stand out. It is also worth looking at the Core Web Vitals, because a faster server response feeds through to perceived loading time.

Define the fallback path before you start

The way back is deliberately short: disable the feature flag, clear caches, purge the reverse proxy, restart workers. Write that sequence down including responsibilities and expected duration, and embed it in your regular maintenance and update process. A documented fallback path lowers the barrier to tackling the change at all.

Using caching for logged-in customers as a revenue lever

The cache rework moves the performance discussion to where money is made. So far mainly anonymous visitors benefited from the full-page cache, while regular customers, B2B buyers and people with a filled cart received the slowest responses. With the sw-cache-hash that break disappears. The price is an honest review of your own extensions, an adjusted expectation of how quickly changes become visible and a cleanly configured reverse proxy.

As a Shopware agency we accompany that step in clearly separated stages so the shop stays sellable throughout:

  1. Suitability check: we review shop, theme and extensions for correct behaviour with caching enabled for logged-in customers and document every finding traceably.
  2. Adjustment: personalised fragments are moved to lazily loaded blocks, cache policies are set per route and deprecated configuration values are replaced.
  3. Test run: in staging we run the two-account test, check cart states, customer group prices and the B2B net view, and automate the comparisons.
  4. Controlled activation: the feature flag is enabled in an agreed window, with a defined fallback path and close observation.
  5. Evidence: hit rate, time to first byte and origin load are measured before and after, so the effect is backed by numbers rather than claims.

If you would like to know where your shop stands regarding the cache rework, we usually start with a compact inventory of extensions and metrics. Get in touch through our contact form - we will classify your current state and name the steps that make the biggest difference in your case.

This is how your shop could look for logged-in regular customers:

B2B E-CommerceDemo

Industrieteile-Portal

This design example shows how a shop with customer group prices, net view and personalised areas can look - with a clear structure and short response times even after login. We build such solutions individually and align the caching layers with your assortment.
Shopware 6HTTP cacheB2BPerformance
Discuss Your Project
Demo
Sources and studies

This article is based on data and information from: Shopware Developer Documentation (Concepts: HTTP Cache, the hosting guide on caches and the reference "Improved HTTP Cache Layer"), Shopware Release Notes 6.7.6.0, shopware/shopware on GitHub (Discussion #3299 on the HTTP Cache Rework and Issue #12756 on cache poisoning), Shopware News ("The new caching system"), Deloitte in cooperation with Google ("Milliseconds Make Millions"), web.dev (time to first byte) and our own project experience. The figures mentioned can vary depending on system, configuration and point in time.

The feature flag CACHE_REWORK is available from 6.7.5.0, and the full changeover shipped with 6.7.6.0 on 13 January 2026 (Shopware Release Notes 6.7.6.0). The new caching typically becomes default behaviour only with the next major release, 6.8.0.0. Until then you decide when to switch.

With correctly implemented extensions, typically not, because the sw-cache-hash includes login state, tax state, currency and customer group in the cache key (Shopware Developer Documentation). Risks arise where plugins or themes render personal content directly into cached HTML. That is exactly why the two-account test belongs in staging before the flag goes live.

Since Shopware 6.7, invalidations are collected and processed in intervals; the default is 5 minutes and can be adjusted through the shopware.invalidate_cache scheduled task (Shopware Developer Documentation). This raises the hit rate considerably but requires adjusted expectations in editorial and purchasing work. For time-critical figures, client-side fragments are the better fit.

As a rule it becomes simpler: the proxy uses the sw-cache-hash as part of the cache key, and the value is announced through the Vary header (Shopware Developer Documentation). Special rules for the former cookies are no longer needed. What you should verify is that the header is passed through completely and not stripped by custom rules.

The HTTP cache stores finished HTML responses of the classic storefront, Store API caching concerns data endpoints for headless frontends, and an object cache such as Redis holds intermediate results of the application. The layers complement each other; which one pays off first depends on architecture and load profile.

In our experience three metrics are enough: cache hit rate split by anonymous and signed-in requests, time to first byte at the 75th percentile with 0.8 seconds as a good target (web.dev) and the remaining load at the origin. Collected before and after activation over comparable periods, the effect can typically be demonstrated clearly - including whether further steps make sense (see also Lighthouse optimisation for Shopware).