Zum Inhalt springen
Core Web Vitals specialists
E-Commerce

Shopware Performance: Faster Loading Times

Make Shopware CE faster with built-in tools: integrated HTTP cache and reverse proxy, cache warmup, Elasticsearch and the performance gain of a 6.x update.

13 min read ShopwareE-CommerceCachingHTTP-CacheElasticsearch

A Shopware shop rarely gets slow where generic performance advice takes aim. Before the first byte reaches the browser, the server has queried categories, prices per customer group, variants and stock levels and rendered a storefront template. This server-side work decides the Time to First Byte, and web.dev names 0.8 seconds (web.dev) or less as a good value, while anything over 1.8 seconds (web.dev) counts as poor. This is no lab figure: the Deloitte study Milliseconds Make Millions measured across 37 brands that a mobile load time 0.1 seconds (Deloitte) faster increased retail conversions by 8.4 percent (Deloitte) and travel conversions by 10.1 percent (Deloitte). This article shows how to use the built-in tools of Shopware CE for exactly this: the integrated HTTP cache with reverse proxy, targeted cache warmup and invalidation, the correctly excluded routes for cart and checkout, Elasticsearch or OpenSearch to offload the database, theme compilation and media delivery, and the performance gain of an update to the current 6.x generation.

Shopware CE: HTTP Cache and Reverse Proxy in the ShopThe built-in cache serves pages from RAM -- cart and checkout stay dynamicRequestStorefrontReverse Proxy (Varnish)built-in HTTP cachehigh hit rate, low TTFBHITCache HIT: page from RAMresponse in millisecondsMISSShopware app (PHP / Symfony)Cache MISS: page is renderedCart + Checkoutdeliberately not cachedElasticsearch / OpenSearchoffloads the databasefor large catalogsMySQL / MariaDBproduct and order dataslow query log activeRedisobject and session cache0.1 to 0.5 ms access0.8 sgood TTFB threshold(web.dev)8.4 %more retail conversionsper 0.1 s (Deloitte)10.1 %more travel conversionsper 0.1 s (Deloitte)43 %sites with good INP2024 (Web Almanac)A good TTFB is 0.8 seconds or less (web.dev); a mobile load time 0.1 s fasterincreased retail conversions by 8.4 and travel conversions by 10.1 percent (Deloitte, Milliseconds Make Millions).Illustrative architecture of the Shopware cache layers; real-world values vary by setup.

Why Shopware Has Its Own Performance Levers

General tips like compressing images or trimming scripts help any frontend but fall short for a shop. A shop system renders most pages server-side from many data sources, and personalized elements like the mini cart or customer-specific prices complicate any naive full-page caching. Shopware CE ships its own tools for exactly these problems, tools that reach deeper than a cache header in the web server. Whoever knows and configures them correctly cuts the response time at the root instead of merely masking it in the browser. The commercial lever is considerable: in the same Deloitte analysis, average order value in retail rose by 9.2 percent (Deloitte) per 0.1 seconds.

This article deliberately sets itself apart from the generic topics. How a reverse proxy and an in-memory store fundamentally work at the infrastructure level is covered by our article on caching strategies with Varnish and Redis; how to speed up slow queries with indexes and by resolving N+1 patterns is shown by the piece on database query optimization in the shop. Here, by contrast, the focus is on the Shopware tools themselves: which configuration activates these layers, how invalidation interlocks cleanly and which routes must stay excluded. The link to the Core Web Vitals runs throughout, because a low TTFB directly improves Largest Contentful Paint.

HTTP Cache, Reverse Proxy and ESI in Brief

The HTTP cache stores fully rendered pages so that identical follow-up requests are answered without re-rendering. A reverse proxy like Varnish sits in front of the application and serves these cached pages from memory. ESI (Edge Side Includes) splits a page into cacheable and dynamic fragments, so the page frame is cached while personalized building blocks like the cart are inserted fresh on each request.

The Integrated HTTP Cache and the Reverse Proxy

Shopware CE ships an HTTP cache based on the Symfony HttpCache that stores complete storefront responses. It is enabled via the environment variable SHOPWARE_HTTP_CACHE_ENABLED in the .env (Shopware Developer Documentation). On a cache hit, the shop serves an already rendered page without invoking PHP, Twig rendering and the database again. This brings server-side processing time from hundreds of milliseconds down to the single-digit millisecond range and puts the good TTFB threshold of 0.8 seconds (web.dev) within reach.

The built-in cache suits a single server. As soon as more load or several instances come into play, Shopware recommends a real reverse proxy like Varnish in front. From Shopware 6.6 onward it is set up via the configuration key shopware.http_cache.reverse_proxy, including the BAN method for invalidation, the list of Varnish hosts and the maximum number of parallel invalidations (Shopware Developer Documentation). Shopware provides a pre-configured Varnish Docker image with a default VCL for this, so the cache rules do not have to be written from scratch.

.env
# Enable the integrated HTTP cache
SHOPWARE_HTTP_CACHE_ENABLED=1

# Default cache time for storefront pages (seconds)
SHOPWARE_HTTP_CACHE_DEFAULT_TTL=7200
config/packages/prod/shopware.yaml
shopware:
  http_cache:
    reverse_proxy:
      enabled: true
      ban_method: 'BAN'
      hosts:
        - 'http://varnish:6081'
      max_parallel_invalidations: 3

Soft Purge Instead of Hard Invalidation

By default, Varnish uses hard purges that discard an entry immediately. A soft purge instead keeps the old page in the cache and continues to serve it while a fresh version is fetched in the background (Shopware Developer Documentation). This way the user never sees a wait caused by a cold cache, and the shop stays responsive even during an invalidation wave. For heavily frequented category pages, this is an effective safeguard against load spikes.

Cache Warmup and Targeted Invalidation

An empty cache after a deployment is treacherous: the first visitor to each page pays the full rendering time, and with many concurrent hits the still-cold application can be overloaded. Cache warmup therefore fills the store in advance by automatically requesting the most important pages such as the homepage, categories and product details. This way the first real visitor already hits a warm cache and a low TTFB instead of paying for the buildup. The warmup ideally belongs in the deployment process, right after clearing the cache.

deploy.sh
# Clear the cache and rebuild containers
bin/console cache:clear

# Warm up the HTTP cache in a targeted way (storefront URLs)
bin/console http:cache:warm:up

# Generate the sitemap in a dedicated cronjob, not per request
bin/console sitemap:generate

Just as important as filling is targeted clearing. A cache is only as good as its invalidation: when a price or stock level changes, exactly the affected page must be refreshed, not the whole cache. Shopware solves this via cache tags. The reverse proxy cache shares the same invalidation mechanism and the same tags with the object cache, so a product change invalidates both the object cache and the HTTP cache of the affected pages (Shopware Developer Documentation). This tight coupling saves custom invalidation logic and prevents customers from seeing stale prices.

Delayed Invalidation Against Cache Storms

When an import changes hundreds of products at once, an immediate invalidation can trigger a wave of recalculations and overload the database. Shopware offers a delayed, batched invalidation for this that collects tags and processes them in controlled blocks. This smooths load spikes after bulk changes. After every import, check the cache hit rate, because overly aggressive invalidation lowers the hit rate and thus the effect of the entire cache layer.

Cart and Checkout: the Correctly Excluded Routes

Not every page belongs in the cache. Cart, checkout, customer account and wishlist differ per user, and if they were cached, the next visitor would see someone else's data. These routes must deliberately stay dynamic. Shopware detects an active cart or a login session and serves the corresponding pages uncached, so every customer sees their own state. This is not a loss of performance but a necessity: the cache steps in where content is the same for everyone and steps back where it is individual.

  • Cart and mini cart: tied to the session and must never be shared.
  • Checkout with address, shipping and payment steps: contain personal data.
  • Customer account, order history and wishlist: are individual per login.
  • Customer-specific prices and tiered prices: differ per customer group.
  • Forms with CSRF tokens: would break from the cache with invalid tokens.

For the common case where only a small part of an otherwise public page is personalized, such as the cart icon with the item count, Shopware falls back on split delivery: the page frame is cached while the personalized block is inserted via ESI or as a lazily loaded fragment. This keeps the category page fully cacheable for guests without the cart counter showing wrong values. This clean separation is why a well-configured shop reaches high hit rates despite personalization.

The Most Expensive Configuration Mistake

If a personalized route is accidentally made cacheable, in the worst case a customer sees another customer's data. After every change to the cache configuration, therefore, specifically verify that cart, checkout and customer account never come from the cache. A controlled look at the response headers of these routes reliably shows whether they are marked as non-cacheable. This single test guards against the most consequential mistake of the entire cache layer.

Elasticsearch and OpenSearch for Large Catalogs

For small shops, the relational database handles product lists, filters and search effortlessly. But once the catalog grows to tens of thousands of articles with many properties, filter and search queries become a brake because they run over large tables and evaluate complex joins. This is exactly where connecting Elasticsearch or OpenSearch comes in: it takes over search, navigation and listing aggregations and thereby noticeably offloads the database. The storefront reads the result lists from the search index instead of from MySQL, which significantly lowers the response time of large category and search pages.

Search and Filters

Full-text search, facets and filters run in the search index instead of over large relational joins. This keeps even catalogs with many properties fast.

Listing Aggregations

Category pages with sorting, price ranges and availability are served from the index. The database stays free for orders and stock levels.

Controlled Fallback

With SHOPWARE_ES_THROW_EXCEPTION you prevent a silent fallback to MySQL on index errors, so problems become visible instead of burdening the database.

elasticsearch-setup.sh
# Build the search index for the storefront
bin/console es:index

# Do not silently fall back to MySQL on index errors (.env)
#   SHOPWARE_ES_THROW_EXCEPTION=1

# Optional: offload the admin search via OpenSearch
bin/console es:admin:index

The effort does not pay off for every shop. A catalog with a few hundred products often runs faster without a search index, because the additional service costs operation and memory. From several tens of thousands of articles or with many concurrent filter accesses, the ratio reverses. In addition, classic optimization of the remaining queries stays important, as described in the piece on database query optimization in the shop; the search index does not replace clean indexes but takes the most expensive load off the database. A sound performance analysis therefore measures in advance which page type really dominates the database time.

Theme Compilation and Media Delivery

Part of Shopware performance is created at deployment time. The storefront theme is compiled from SCSS and JavaScript into delivered assets, and this compilation belongs in the build process, not in live operation. If the theme is built in advance in production mode and the assets are installed correctly, the server no longer has to compile anything at runtime. Together with a clean OPcache configuration that keeps compiled PHP code in memory, the processing time per request drops further.

build.sh
# Compile the theme in production mode
bin/console theme:compile

# Copy compiled assets to the public path
bin/console asset:install

# Pre-generate thumbnails for new media
bin/console media:generate-thumbnails

The second area is media delivery. Shopware generates graduated thumbnails from each product image, loaded to match the display size, and supports modern formats like WebP. If the thumbnails are pre-generated and delivered with long cache times and a content hash in the filename, the browser loads them only once. How to cut image weight further is shown by the piece on image optimization with WebP and AVIF; how an upstream edge network speeds up delivery is deepened by the article on CDN and edge caching for shops. This pays off measurably, because in the HTTP Archive Web Almanac only 33 percent (HTTP Archive Web Almanac) of HTML documents were delivered via a CDN in 2024, although 54 percent (HTTP Archive Web Almanac) of all requests already came from a CDN.

Built-in ToolActs OnBiggest Lever For
Integrated HTTP cacheStorefront TTFBGuest traffic, categories
Reverse proxy (Varnish)Response time under loadHigh traffic, multiple servers
Cache warmupFirst hit after deployFrequent deployments
Elasticsearch / OpenSearchSearch and filter timeLarge catalogs
Theme compilationProcessing timeEvery shop in production mode
Thumbnails and WebPImage weight, LCPImage-heavy product pages

The Performance Gain of an Update to 6.x

An often underestimated lever is the update itself. The current 6.x generation of Shopware CE brings performance improvements that take effect without any development work of your own. From Shopware 6.6 onward, the cart can be stored compressed with zstd, saving memory and transfer (Shopware Developer Documentation). Newer versions optionally load reduced product data in lists, so only the short text is loaded instead of the full description, and they allow taking the product stream indexer and the scheduled sitemap generation out of the request path (Shopware Developer Documentation). Each of these adjustments relieves the hot path on which the user waits.

On top of that comes the jump to current PHP versions that an update pulls along. Newer PHP generations with preloading and JIT process the same code faster, and the current 6.x generation experimentally supports the Speculation Rules API for prefetching the likely next page. These advances add up to a noticeably lower response time without changing anything in your own code. A version several generations back forfeits exactly these gains.

The Update Is a Performance Project

Whoever lingers on an old 6.x version forgoes cache improvements, more efficient data structures and faster PHP runtimes that newer versions bring at no extra cost. A planned update to the current state is therefore not just maintenance but one of the most effective and cheapest performance measures of all.

The most effective optimization is often the one already built into the system: enable the integrated HTTP cache, put the reverse proxy in front, offload the database with a search index and update regularly to the current version. Only after that is it worth looking at the fine details.

Project experience from 50+ performance projects

Measure, Safeguard and Stay Fast for Good

None of these measures runs on autopilot. The cache hit rate falls with every new extension, every additional cookie and every careless piece of personalization. That is why the effect belongs measured continuously: the reverse proxy hit rate, the TTFB per page type and the response time under real load. Only this observation shows whether a category page still comes from the cache or is being rendered again. This is closely tied to server optimization and TTFB reduction, which keeps the time to first byte continuously in view, and to deliberately lowering the TTFB as a metric.

The connection to frontend delivery remains: a low TTFB moves Largest Contentful Paint forward, but images, fonts and scripts decide the rest. That is why server-side work interlocks with frontend optimization. How strongly load time affects revenue is made clear by the piece on page speed, conversion rate and revenue; and because the choice of server co-determines the TTFB, the article on choosing hosting and server load time rounds out the picture. Whoever runs not a shop but a WordPress site will find the fitting levers in the piece on common WordPress performance bottlenecks. That the path is worthwhile is shown by the trend in the Web Almanac: in 2024, 43 percent (HTTP Archive Web Almanac) of websites reached a good INP value, a clear advance over previous years.

This article is based on data from: Shopware Developer Documentation (HTTP cache, reverse proxy, cache invalidation, Elasticsearch and performance tweaks), web.dev (Time to First Byte, Largest Contentful Paint and Interaction to Next Paint and their thresholds), HTTP Archive Web Almanac 2024 (Core Web Vitals, CDN usage and compression) and Deloitte (Milliseconds Make Millions). All statistics mentioned were verified at the time of publication. The architecture in the mockup illustrates the Shopware cache layers.