Performance
A diagnosis-first guide to Shopware 6.7 performance: a baseline you can take with curl, five checks in order (HTTP cache, queue, PHP and database, search, frontend), and where each result points.
Find the slow layer before you change a setting. Take a baseline with curl, then work through five checks in this order: HTTP cache, queue, PHP and database on a cache miss, search, frontend. Each check takes minutes and points to the checklist items or guides that fix that layer. Run the same baseline after every change so you can see what helped.
Checked against: Shopware 6.7.15.1, October 2026. The cache states, the profiler integrations and the queue commands below were read from that release. The Core Web Vitals thresholds come from web.dev.
The performance checklist lists 16 settings. Which ones matter for your store depends on where the time goes. Tuning the mail queue does nothing for a store whose pages never hit the cache.
This guide is the step before the checklist. It gives you a baseline and five checks, in the order that rules things out fastest, and every check ends with a pointer to the settings or guides for that layer. The measurements are yours. Your hosting, your catalogue and your traffic decide what a normal result looks like, so the guide ships no benchmark numbers.
Pick three URLs a logged-out visitor can open: the homepage, a category listing and a product page. Request each one twice and note the time to first byte (TTFB), the time until the server starts sending the page.
for url in \
https://shop.example.com/ \
https://shop.example.com/category-name/ \
https://shop.example.com/product-name/SW10001; do
for run in 1 2; do
curl -s -o /dev/null -w "run $run ttfb %{time_starttransfer}s %{http_code} $url\n" "$url"
done
done
curl sends no cookies, so Shopware sees a visitor who is not logged in and has an empty cart. That is the traffic the HTTP cache serves. Shopware sets a sw-states cookie with the states logged-in and cart-filled, and a request that carries either state skips the cache.
Compare the two runs with each other and look at the gap. The absolute numbers depend on your hosting, so keep them as your own reference and run the same loop after every change. If you run several app servers behind a load balancer with a file-based cache, run 2 can land on a server that has not cached the page yet, so repeat the request a few times.
Two equal slow runs mean the page is rebuilt on every request. Shopware's HTTP cache is on by default in 6.7 (SHOPWARE_HTTP_CACHE_ENABLED defaults to 1), so look for the usual reasons it is not doing its job:
SHOPWARE_HTTP_CACHE_ENABLED=0. Check the .env files and the server's environment variables.
cf-cache-status).
cart-filled state and never sees a cached page.
Once pages are cached, two things decide how well the cache holds up under load: where it is stored and how invalidations are handled. The checklist's Cache group covers both. Move the app and system cache to Redis matters because the file cache slows down under load and cannot be shared between app servers. Keep pending cache invalidations in Redis matters because by default they queue in a MySQL table that can deadlock on a busy store. The checklist download form is further down this page.
Late order mails, imports that stall, indexing that lags behind product saves and admin actions that seem to do nothing are queue symptoms. One command shows the backlog:
bin/console messenger:stats
It prints the number of waiting messages per transport. It works for transports that can count their messages, and both the Doctrine transport (the default) and the Redis transport can. Run it a few times over several minutes:
A common cause of a queue nobody consumes is the admin worker: it only processes the queue while someone has the Administration open. The checklist item Switch off the admin worker and run real workers explains the fix, and its Queue and cron group covers scheduled tasks, mail and the sitemap. To take the queue off MySQL entirely, follow the Redis Streams guide.
Run 1 from the baseline, and every logged-in or cart-filled request, pays the full cost of building a page. Two views show where that time goes.
Shopware ships a profiler integration called ServerTiming. Enable it and each response carries a Server-Timing header that lists the traced steps with their duration in milliseconds.
# config/packages/shopware.yaml
shopware:
profiler:
integrations:
- ServerTiming
Reload a slow page, open the Network panel in your browser's dev tools and look at the Timing tab of the document request. curl -sI shows the same header in a terminal.
Important: The header is visible to every client. Enable it on staging, or switch it off again as soon as your measurement on production is done.
Turn on MySQL's slow query log for a while and let real traffic fill it:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;
This logs every statement slower than one second. SHOW VARIABLES LIKE 'slow_query_log_file' prints the log path, and mysqldumpslow groups similar statements. Set slow_query_log back to 'OFF' when you are done, because the log grows with traffic. MariaDB uses the same variables.
For a call tree instead of a list of steps, use a profiler. Shopware also ships integrations for Tideways and Datadog, and they are enabled in the same shopware.profiler.integrations list.
Once you know which steps dominate, the checklist removes work from them. Its PHP and deploys group (OPcache, the compiled environment file, the Composer classmap) cuts per-request overhead. Its Catalogue and storefront group (reduced product data in listings, the product stream indexer) cuts work per page and per product save.
Slow listings, slow filters and slow search results can mean search is running against MySQL. When OpenSearch or Elasticsearch fails, Shopware quietly runs the search against MySQL, and on a large catalogue that fallback can overload the database. If the store does not run OpenSearch at all, skip to Step 5.
bin/console es:status
es:status reports cluster health and whether indexing is current. A cluster that is not green, or a command that cannot connect, is your answer. The Elasticsearch/OpenSearch guide covers the setting that turns the silent fallback into a visible error, and the checklist item Stop search from falling back to MySQL is the short version.
If the server answers quickly and the page still feels slow, measure real visitors before you touch the theme. PageSpeed Insights shows field data from the Chrome UX Report for URLs with enough traffic, with a Lighthouse lab run underneath. Google rates a page as good when, at the 75th percentile of visits, Largest Contentful Paint (LCP) is 2.5 seconds or less, Interaction to Next Paint (INP) is 200 milliseconds or less, and Cumulative Layout Shift (CLS) is 0.1 or less.
Server time is part of LCP, so a slow TTFB caps how good LCP can get. That is why the server layers come first.
The checklist includes one frontend setting: Turn on the Speculation Rules API, an Administration setting available since 6.6.10.0. Once a shopper hovers over or presses a link, the browser starts rendering the next page, so the click lands on a page that is already built. Beyond that, what to change depends on your theme. Image sizes, fonts and third-party scripts are the usual places to look, and this guide stops at measuring them.
Step 3. Cache misses are expensive. Server-Timing and the slow query log show why.
Step 1. Pages are not served from a cache.
Step 2. Check the queue backlog.
Step 4. Check that search runs on OpenSearch.
Step 3. Those visitors skip the HTTP cache, so every request builds the page.
Step 5. Measure real visitors, then look at the theme.
The product import case study shows the queue side of this. On a 530,000-SKU catalogue a full product sync took 33 hours. Parallel batches and a delta sync brought it down to 2.8 hours. Read the product import case study for the details.
messenger:stats shows whether background work keeps up.
Written by Huzaifa Mustafa
Free PDF
16 settings that make a Shopware 6 store faster. Each one comes with the exact config, the version it needs and what it can break.
Your address goes to our inbox and nowhere else. No newsletter. Privacy policy
Your checklist is ready.
Start with the audit sheet at the front. Stuck on an item? Send us the details and we reply within 24 hours.
That didn't go through. Try again, or email us at [email protected]
Go deeper on the layers above:
Run the baseline, then bring the numbers and get a second pair of eyes from a Certified Shopware Developer.
Talk to an Engineer