# Shopware best practices

This page collects practical recommendations for running a fast, stable Shopware 6 store on TurboStack. The platform already applies a tuned baseline when you deploy; the optimizations below build on it so your storefront stays responsive under load.

## What TurboStack configures for you

When you deploy a `shopware` app, the platform provisions and tunes the following automatically:

- **Nginx vhost** tuned for Shopware, with long static-asset expiry, the `recovery`/installer routes, and PHP-FPM via a dedicated FastCGI backend (`/var/www/<user>/<app>/nginx/50main.conf`).
- **Document root** is `public_html`, symlinked to the Shopware `public/` directory so the application root stays outside the web root.
- **Redis** for both the object/HTTP cache and PHP sessions, configured through `config/packages/hostedpower.yaml` (cache app + object, HTTP, and tags pools; sessions on a persistent Redis socket).
- **Message queue transport** on Redis, set via `MESSENGER_TRANSPORT_DSN` in `.env.local` (`symfony/redis-messenger` is installed during provisioning).
- **Varnish full-page cache** with a Shopware-aware VCL (`/etc/varnish/conf.d/50_main.vcl`) using xkey-based tag invalidation and BAN/PURGE support, when `varnish_enabled` is set.
- **HTTP cache** enabled in `.env.local` (`SHOPWARE_HTTP_CACHE_ENABLED=1`, default Time to Live (TTL) `7200`).
- **MySQL tuning** for Shopware, including `group_concat_max_len` raised to handle large product datasets (`/etc/mysql/after.conf.d/shopware.cnf`).
- **Log rotation** for everything under `shopware/var/log/`, plus the `shopware-cli` tool for maintenance and build tasks.
- **OpenSearch wiring** in `.env.local` (`OPENSEARCH_URL`), ready to enable when you need search at scale.

> [!NOTE]
> Settings live in `.env.local` and `config/packages/hostedpower.yaml` in your app directory. Run `bin/console cache:clear` after changing them.

## Recommended optimizations

- **Run in production mode** - keep `APP_ENV=prod` so Shopware uses compiled, cached containers and assets.
- **Keep Redis for cache and sessions** - already configured; verify both services are enabled under [Services](../../platform/hosts/services.md).
- **Run the message queue** - process the queue and scheduled tasks continuously so emails, indexing and background jobs do not accumulate. See [Message-queue consumers](#message-queue-consumers) below.
- **Enable Varnish** - set `varnish_enabled` for the storefront; it reduces PHP load on catalog and CMS pages.
- **Enable OpenSearch for large catalogs** - set `SHOPWARE_ES_ENABLED=1` and `SHOPWARE_ES_INDEXING_ENABLED=1`, then run `bin/console es:index` to offload product search from MySQL.
- **OPcache** - keep it on for the PHP runtime; it is part of the platform's PHP-FPM tuning.
- **Optimize media** - generate thumbnails ahead of traffic with `bin/console media:generate-thumbnails`; serve images via a Content Delivery Network (CDN) using the configured CDN strategy.
- **Warm the cache** - after deploys, run `bin/console cache:warmup` (the platform also crawls the storefront to prime Varnish).

## Message-queue consumers

Shopware offloads emails, search indexing and other background work to a message queue, which TurboStack routes through Redis. In production you run the consumer from the command line instead of the browser-based admin worker.

Disable the admin worker in `config/packages/shopware.yaml` so the queue does not depend on an open Administration tab:

```yaml
shopware:
    admin_worker:
        enable_admin_worker: false
```

Then run the consumer and the scheduled-task runner. The `--time-limit` and `--memory-limit` flags stop a worker cleanly so a process manager can restart it fresh:

```bash
bin/console messenger:consume async low_priority --time-limit=60 --memory-limit=512M
bin/console scheduled-task:run
```

Run these as persistent [user system services](../../technologies/system-services/manage-user-services.md) so they restart on failure and survive logout. To clear a backlog faster, run several consumers in parallel, but keep the total within the host's processor budget (see [Scale throughput with more instances](../../technologies/system-services/manage-user-services.md#scale-throughput-with-more-instances)).

## Sizing and scaling

Defaults are auto-tuned to the host's resources, so start there and scale on evidence, not guesswork. Override these only with measured data from real traffic:

| Variable | Tune when |
| --- | --- |
| `mysql_innodb_size` | InnoDB buffer pool for the Shopware database |
| `redis_memory` | Redis memory ceiling for cache and sessions |
| `varnish_cache_size` | Varnish full-page cache size |
| `elasticsearch_heap_size` | OpenSearch heap when search is enabled |

See [Performance tuning](../../concepts/performance-tuning.md) for the methodology. Scale vertically first (CPU, RAM, faster storage) before adding complexity.

> [!TIP]
> Large catalogs benefit most from more InnoDB buffer pool and OpenSearch. Heavy storefront traffic benefits most from Varnish and Redis. Tune the one that matches your bottleneck.

## Stability

- **Back up before changes** - verify scheduled backups cover both the database and the `shopware/` files; see [Backups](../../platform/hosts/backups.md).
- **Watch the host** - monitor the [Health](../../platform/hosts/health.md) tab for CPU, memory, and disk pressure.
- **Stay current** - keep Shopware, plugins, and the PHP runtime patched for security and performance fixes; pin `shopware_version` deliberately.
- **Test on a staging clone** - try plugin and version upgrades on a copy first, then publish to production.

## Related

- [Deploy Shopware](deploy.md)
- [Shopware reference](reference.md)
- [Troubleshooting Shopware](troubleshooting.md)
- [How to manage user system services](../../technologies/system-services/manage-user-services.md)
- [Services](../../platform/hosts/services.md)
- [Performance tuning](../../concepts/performance-tuning.md)
