A slow shop costs revenue. Various studies show that users abandon a page if it takes longer than three seconds to load. Shopware 6 provides all the tools needed to achieve fast load times even with large product catalogs and high traffic — you just have to use them correctly.
1. Elasticsearch / OpenSearch for Product Search and Listings
Shopware 6 natively supports Elasticsearch and OpenSearch. Without a search engine, Shopware uses its own DAL (Data Abstraction Layer) with MySQL/MariaDB for all product queries — which becomes noticeably slower starting at around 10,000 products.
Installation and Activation
# In .env
SHOPWARE_ES_ENABLED=1
SHOPWARE_ES_HOSTS=localhost:9200
SHOPWARE_ES_INDEXING_ENABLED=1
SHOPWARE_ES_INDEX_PREFIX=sw
# Build the initial index
php bin/console es:index
php bin/console es:create:alias
Important Configuration in config/packages/shopware.yaml
shopware:
elasticsearch:
enabled: true
hosts:
- '%env(SHOPWARE_ES_HOSTS)%'
index_prefix: '%env(SHOPWARE_ES_INDEX_PREFIX)%'
throw_exception: true
# Enable product fields for aggregations
product:
custom_fields_mapping:
my_custom_field_text:
type: text
fields:
keyword:
type: keyword
Pitfalls
- Re-indexing after changes: Every product change triggers a re-index. When making bulk changes, keep the Message Queue supervisor running.
- Mapping changes: New custom fields require running
es:indexagain. - Heap size: Elasticsearch requires at least 1 GB of heap — configure it in
jvm.options:-Xms1g -Xmx1g.
2. Redis for Session, Cache, and Queue Storage
Redis significantly accelerates Shopware in three areas: session storage, object cache, and as a message queue backend.
Configuring Redis
# config/packages/framework.yaml
framework:
session:
handler_id: 'redis://localhost:6379/0'
cache:
app: cache.adapter.redis
system: cache.adapter.redis_tag_aware
pools:
cache.adapter.redis:
adapter: cache.adapter.redis
provider: 'redis://localhost:6379/1'
Redis for the Shopware Cache
# config/packages/shopware.yaml
shopware:
cache:
invalidation:
delay: 0
count: 150
In config/packages/prod/framework.yaml:
framework:
cache:
prefix_seed: '%env(APP_SECRET)%'
app: cache.adapter.redis_tag_aware
pools:
cache.app:
tags: true
Redis Connection Pool with Sentinel (High Availability)
framework:
cache:
pools:
cache.app:
adapter: cache.adapter.redis_tag_aware
provider: 'redis+sentinel://sentinel1:26379,sentinel2:26379,sentinel3:26379?redis_sentinel=mymaster'
Message Queue on Redis
# config/packages/messenger.yaml
framework:
messenger:
transports:
async:
dsn: 'redis://localhost:6379/messages'
options:
auto_setup: false
delete_after_ack: true
3. HTTP Cache (Varnish / Symfony Reverse Proxy)
Shopware supports two HTTP cache backends: the built-in Symfony reverse proxy and Varnish. The HTTP cache makes pages extremely fast for non-logged-in users because no PHP execution is required.
Activating the Built-in HTTP Cache
The HTTP cache is activated via environment variables — Shopware handles the kernel configuration internally. Manual changes to public/index.php are not necessary.
In .env:
SHOPWARE_HTTP_CACHE_ENABLED=1
SHOPWARE_HTTP_CACHE_DEFAULT_TTL=7200
Cache Tags and Invalidation
Shopware uses cache tags to invalidate precisely. When a product is changed, only pages containing that product are removed from the cache.
<?php
declare(strict_types=1);
namespace MyPlugin\Subscriber;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Storefront\Framework\Cache\CacheResponseSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductInvalidationSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
'product.written' => 'onProductWritten',
];
}
public function onProductWritten(EntityWrittenEvent $event): void
{
foreach ($event->getIds() as $productId) {
// Invalidate the cache tag for this product
// Shopware handles this automatically via the EntityCacheKeyGenerator
}
}
}
Configuring Varnish
For high-traffic setups, Varnish is the better choice. Shopware ships a default.vcl template:
# In .env
SHOPWARE_HTTP_CACHE_ENABLED=1
SHOPWARE_HTTP_REVERSE_PROXY_ENABLED=1
SHOPWARE_HTTP_REVERSE_PROXY_HOSTS=http://localhost:6081
SHOPWARE_HTTP_REVERSE_PROXY_TTL=7200
4. Database Optimization
Not to be neglected: the database. Shopware uses MariaDB/MySQL. Important settings:
# my.cnf / mariadb.conf.d/shopware.cnf
[mysqld]
innodb_buffer_pool_size = 2G # 70-80% of RAM
innodb_log_file_size = 256M
query_cache_type = 0 # Removed in MySQL 8 anyway
max_connections = 300
thread_cache_size = 16
Identifying missing indexes:
-- Find slow queries
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.5;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
5. Asset Optimization
Shopware automatically compresses and bundles assets. Important for production environments:
php bin/console asset:install
php bin/console theme:compile
# Then Brotli/gzip compression via nginx
Conclusion
Performance tuning in Shopware is not a one-time event but an ongoing process. The three most important measures after a base setup:
- Elasticsearch for large product catalogs (starting at ~10,000 products)
- Redis for session, cache, and message queue
- HTTP Cache for all non-personalized pages
With this combination, load times under 500ms are achievable even on complex shops.
Comments
Comments are provided by Remark42. By loading comments, data is transmitted to our comment server.