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.
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 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.
# Enable the integrated HTTP cache
SHOPWARE_HTTP_CACHE_ENABLED=1
# Default cache time for storefront pages (seconds)
SHOPWARE_HTTP_CACHE_DEFAULT_TTL=7200shopware:
http_cache:
reverse_proxy:
enabled: true
ban_method: 'BAN'
hosts:
- 'http://varnish:6081'
max_parallel_invalidations: 3Soft Purge Instead of Hard Invalidation
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.
# 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:generateJust 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
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
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.
# 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:indexThe 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.
# 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-thumbnailsThe 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 Tool | Acts On | Biggest Lever For |
|---|---|---|
| Integrated HTTP cache | Storefront TTFB | Guest traffic, categories |
| Reverse proxy (Varnish) | Response time under load | High traffic, multiple servers |
| Cache warmup | First hit after deploy | Frequent deployments |
| Elasticsearch / OpenSearch | Search and filter time | Large catalogs |
| Theme compilation | Processing time | Every shop in production mode |
| Thumbnails and WebP | Image weight, LCP | Image-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
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.
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.