After delivering 162+ custom Shopware 6 plugins across dozens of projects, I have seen the same mistakes repeated by teams new to the platform. Shopware 6 is not just another PHP framework with a store bolted on. Its architecture demands a specific mindset, and teams that treat it like Magento or WooCommerce end up with brittle code that breaks on every update.
The Decoration Pattern Changes Everything
Most PHP developers reach for inheritance first. In Shopware 6, decoration is the primary extension mechanism. Instead of overriding a class, you wrap it. This matters because:
- Upgrades do not break your code. Decorated services survive Shopware core updates because you are extending behavior, not replacing it.
- Multiple plugins coexist. Two plugins can decorate the same service without conflict. Inheritance creates collisions.
- Testing gets simpler. You test your decorator in isolation, not the entire service chain.
The Shopware developer documentation covers the mechanics, but the documentation does not tell you when decoration is the wrong choice. For performance-critical paths like cart calculation or search indexing, decoration adds overhead. In those cases, replacing the service entirely or using subscribers is the better call.
Common Mistakes That Cost Agencies Months
I have audited plugins from other agencies that made the same mistakes repeatedly:
- Overriding admin components instead of extending them. When Shopware updates the base component, the override breaks silently. Component extensions survive because they layer on top.
- Storing state in plugin services. Shopware’s service container reuses instances. If your service holds request-specific state, you get data leaking between requests. Always use request-scoped data or the session.
- Ignoring the plugin lifecycle. The
install,update,activate, anddeactivatemethods exist for a reason. Plugins that skip proper migration handling corrupt databases on update. I have seen a single missing migration take a production shop offline for 8 hours. - Writing synchronous event subscribers for heavy operations. A subscriber that calls an external API during
product.writtenwill block the admin save. Use the message queue instead.
Data Handling at Scale
When you are importing 500K+ SKUs (as I did in one project, cutting import time from 33 hours to under 3), the standard DAL write operations are not enough. You need:
- Batch processing with configurable chunk sizes
- Redis-backed queuing for async operations
- Direct DBAL writes for bulk inserts (bypassing the DAL when performance demands it)
The DAL is excellent for application logic. For ETL operations at scale, it becomes a bottleneck you need to work around deliberately. The key is knowing where that boundary lies: anything under 10,000 entities per operation is fine with the DAL. Above that, benchmark your specific use case and consider DBAL.
Plugin Architecture That Survives
Every plugin I build follows the same structure:
- Strict service decoration over class extension
- Configuration via plugin config, not hardcoded values
- Message queue integration for anything that takes longer than a request cycle
- Migration-based schema changes that handle both install and update paths
- Admin module extensions through component overrides, not replacements
This approach means my plugins work across Shopware minor versions without modification. That is not a nice-to-have. For agencies managing 20+ stores, it is the difference between a routine update and a week of debugging.
The Integration Reality
Most Shopware projects in the DACH region are not standalone shops. They connect to ERPs (SAP, Microsoft Dynamics, Sage), PIMs (Akeneo, Pimcore), and warehouse systems. Each integration has its own data format, sync frequency, and failure modes.
The pattern that works: dedicated sync services per integration, each with its own retry logic, logging, and circuit breaker. Never couple your shop logic to an external system’s availability.
I built exactly this pattern for a pharmaceutical distributor syncing 300K+ SKUs with zero fulfillment errors, and for a B2B platform integrating real-time ERP quotes via OAuth2 REST APIs.
The Shopware 5 to 6 Migration Factor
Many DACH shops are still running Shopware 5. If you are planning a migration, understand that Shopware 6 is a complete rewrite. Your Shopware 5 plugins cannot be ported. They must be rebuilt from scratch using the new architecture.
This is actually an advantage. You get to shed years of technical debt and build clean plugins using decoration, the new admin, and the Flow Builder. I have handled full platform migrations with zero downtime by running both systems in parallel during the transition.
What This Means for Your Project
If you are planning a Shopware 6 project, here is what matters:
- Ask about decoration vs. inheritance. If your developer defaults to class overrides, they will create upgrade headaches.
- Demand performance testing with production-scale data. A plugin that works with 1,000 products may collapse at 100,000.
- Insist on message queue usage. Synchronous operations in event subscribers are the number one cause of storefront slowdowns.
- Check migration handling. Ask how the plugin handles
update()for existing installations. A plugin that only works on fresh installs is a ticking time bomb.
I have written about specific implementations in my case studies. If you are facing a Shopware challenge, get in touch.