{"@attributes":{"version":"2.0"},"channel":{"title":"Spryker Documentation","description":"Spryker documentation center.","link":"https:\/\/docs.spryker.com\/","lastBuildDate":"Fri, 03 Apr 2026 12:40:38 +0000","generator":"Jekyll v4.2.2","item":[{"title":"Keeping dependencies updated for performance","description":"Keeping your project's Spryker module dependencies up to date is critical for maintaining optimal performance, security, and reducing long-term upgrade efforts.\n\n## Why keep dependencies updated\n\nUpdating dependencies regularly provides several practical benefits:\n\n1. **Risk of security vulnerabilities**: Most recent versions contain necessary fixes to all known vulnerabilities.\n2. **Performance and resource consumption optimizations**: Spryker continuously releases performance improvements based on real-life experiences and scenarios.\n3. **Decreasing upgrade efforts**: Distributing upgrades across many smaller steps is much easier than doing one massive upgrade later.\n\n## Key resources\n\nThe following resources provide information about performance-related module releases:\n\n- [Security release notes 202512.0](https:\/\/docs.spryker.com\/docs\/about\/all\/releases\/security-releases\/security-release-notes-202512.0.html)\n- [Release notes 202410.0](https:\/\/docs.spryker.com\/docs\/scos\/user\/intro-to-spryker\/releases\/release-notes\/release-notes-202410.0\/release-notes-202410.0.html)\n- [Release notes 202507.0](https:\/\/docs.spryker.com\/docs\/scos\/user\/intro-to-spryker\/releases\/release-notes\/release-notes-202507.0\/release-notes-202507.0.html)\n- [General performance guidelines](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/general-performance-guidelines.html) - contains the list of recent module versions with known performance optimizations\n- [Cart page performance configuration](https:\/\/docs.spryker.com\/docs\/pbc\/all\/cart-and-checkout\/latest\/cart-page-performance-configuration.html)\n\n## Critical module updates\n\nThe following sections list important module updates that include performance improvements. It's recommended that each Spryker project evaluates and applies these updates.\n\n### Product search performance\n\n**spryker\/product-page-search** - Recent versions (for example, `3.38.0` - `3.40.0`) include improvements such as:\n- Caching logic adjustments for product images\n- Potential bulk operation support to make search document writes more efficient\n- Avoiding duplicate locale events\n\n### Session management\n\n**spryker\/session** - at least `^4.17.0`\n- Provides configurable session locking mechanism\n- See [Redis session lock](\/docs\/dg\/dev\/troubleshooting\/troubleshooting-performance-issues\/redis-session-lock.html) for configuration details\n\n**spryker\/session-redis** - at least `^1.11.2`\n- Includes configurable session locker\n- See [Redis session lock](\/docs\/dg\/dev\/troubleshooting\/troubleshooting-performance-issues\/redis-session-lock.html) for setup instructions\n\n### Merchant Portal and Back Office performance with ACL rules\n\n- [spryker\/acl:^3.26.0](https:\/\/github.com\/spryker\/acl\/releases\/tag\/3.26.0)\n- [spryker\/acl-entity:^1.16.0](https:\/\/github.com\/spryker\/acl-entity\/releases\/tag\/1.16.0)\n- [spryker\/gui:^4.11.0](https:\/\/github.com\/spryker\/gui\/releases\/tag\/4.11.0)\n- [spryker\/merchant-profile:^1.9.0](https:\/\/github.com\/spryker\/merchant-profile\/releases\/tag\/1.9.0)\n- [spryker\/merchant-user:^1.9.0](https:\/\/github.com\/spryker\/merchant-user\/releases\/tag\/1.9.0)\n- [spryker\/multi-factor-auth-merchant-portal:^2.1.0](https:\/\/github.com\/spryker\/multi-factor-auth-merchant-portal\/releases\/tag\/2.1.0)\n- [spryker\/product-attribute:^1.18.0](https:\/\/github.com\/spryker\/product-attribute\/releases\/tag\/1.18.0)\n- [spryker\/zed-navigation:^1.15.0](https:\/\/github.com\/spryker\/zed-navigation\/releases\/tag\/1.15.0)\n\n### Back Office performance on category list page\n\n- [spryker\/product-category:\"^4.32.0\"](https:\/\/github.com\/spryker\/zed-navigation\/releases\/tag\/4.32.0)\n\n### Order placement performance\n\n- [spryker\/calculation:^4.14.0](https:\/\/github.com\/spryker\/calculation\/releases\/tag\/4.14.0)\n- [spryker\/discount-calculation-connector:^5.4.0](https:\/\/github.com\/spryker\/discount-calculation-connector\/releases\/tag\/5.4.0)\n- [spryker\/merchant:^3.15.0](https:\/\/github.com\/spryker\/merchant\/releases\/tag\/3.15.0)\n- [spryker\/sales:^11.60.0](https:\/\/github.com\/spryker\/sales\/releases\/tag\/11.60.0)\n- [spryker\/product:^6.49.0](https:\/\/github.com\/spryker\/product\/releases\/tag\/6.49.0)\n- [spryker\/discount:^9.43.0](https:\/\/github.com\/spryker\/discount\/releases\/tag\/9.43.0)\n- [spryker\/product-cart-connector:^4.13.0](https:\/\/github.com\/spryker\/product-cart-connector\/releases\/tag\/4.13.0)\n- [spryker\/company-role:^1.9.1](https:\/\/github.com\/spryker\/company-role\/releases\/tag\/1.9.1)\n- [spryker\/propel:^3.43.0](https:\/\/github.com\/spryker\/propel\/releases\/tag\/3.43.0)\n- [spryker\/sales:^11.63.0](https:\/\/github.com\/spryker\/sales\/releases\/tag\/11.63.0)\n- [spryker\/sales-product-connector:^1.11.1](https:\/\/github.com\/spryker\/sales-product-connector\/releases\/tag\/1.11.1)\n- [spryker\/shipment:^8.24.0](https:\/\/github.com\/spryker\/shipment\/releases\/tag\/8.24.0)\n\n### OMS availability check and order item reservation\n\n- [spryker\/availability:^9.27.0](https:\/\/github.com\/spryker\/availability\/releases\/tag\/9.27.0)\n- [spryker\/stock:^8.10.1](https:\/\/github.com\/spryker\/stock\/releases\/tag\/8.10.1)\n- [spryker\/oms:^11.45.1](https:\/\/github.com\/spryker\/oms\/releases\/tag\/11.45.1)\n- [spryker\/propel:^3.43.0](https:\/\/github.com\/spryker\/propel\/releases\/tag\/3.43.0)\n- [spryker\/sales:^11.63.0](https:\/\/github.com\/spryker\/sales\/releases\/tag\/11.63.0)\n\n### Publish and synchronization (merchant-related)\n\n- [spryker\/merchant-product-offer-storage:^2.6.0](https:\/\/github.com\/spryker\/merchant-product-offer-storage\/releases\/tag\/2.6.0)\n- [spryker\/product-offer-storage:^1.8.0](https:\/\/github.com\/spryker\/product-offer-storage\/releases\/tag\/1.8.0)\n- [spryker\/propel:^3.45.0](https:\/\/github.com\/spryker\/propel\/releases\/tag\/3.45.0)\n\n### Publish and synchronization (product-related)\n\n- [spryker\/price-product:^4.48.0](https:\/\/github.com\/spryker\/price-product\/releases\/tag\/4.48.0)\n- [spryker\/product-page-search:^3.40.0](https:\/\/github.com\/spryker\/product-page-search\/releases\/tag\/3.40.0)\n- [spryker\/product-search:^5.24.1](https:\/\/github.com\/spryker\/product-search\/releases\/tag\/5.24.1)\n- [spryker\/product-storage:^1.47.0](https:\/\/github.com\/spryker\/product-storage\/releases\/tag\/1.47.0)\n- [spryker\/product-offer-storage:^1.10.0](https:\/\/github.com\/spryker\/product-offer-storage\/releases\/tag\/1.10.0)\n- [spryker\/price-product-offer:^1.7.1](https:\/\/github.com\/spryker\/price-product-offer\/releases\/tag\/1.7.1)\n- [spryker\/price-product-offer-storage:^1.5.1](https:\/\/github.com\/spryker\/price-product-offer-storage\/releases\/tag\/1.5.1)\n- [spryker\/price-product-storage:^4.13.0](https:\/\/github.com\/spryker\/price-product-storage\/releases\/tag\/4.13.0)\n- [spryker\/product-image:^3.20.1](https:\/\/github.com\/spryker\/product-image\/releases\/tag\/3.20.1)\n- [spryker\/product-category-storage:^2.11.0](https:\/\/github.com\/spryker\/product-category-storage\/releases\/tag\/2.11.0)\n- [spryker\/product-category-search:^1.2.1](https:\/\/github.com\/spryker\/product-category-search\/releases\/tag\/1.2.1)\n- [spryker\/propel:^3.47.0](https:\/\/github.com\/spryker\/propel\/releases\/tag\/3.47.0)\n  - Note: If you still use destructive deployments, update the `config\/install\/destructive.yml` file. You can copy it from any demo shop.\n- [spryker\/event-behavior:^1.32.0](https:\/\/github.com\/spryker\/event-behavior\/releases\/tag\/1.32.0)\n- [spryker\/synchronization-behavior:^1.13.0](https:\/\/github.com\/spryker\/synchronization-behavior\/releases\/tag\/1.13.0)\n\n### Publish and synchronization (Category tree build logic)\n\n- [spryker\/category:\"^5.23.0\"](https:\/\/github.com\/spryker\/category\/releases\/tag\/5.23.0)\n- [spryker\/category-storage:\"^2.12.0\"](https:\/\/github.com\/spryker\/category-storage\/releases\/tag\/2.12.0)\n- [spryker\/propel-orm:\"^1.22.0\"](https:\/\/github.com\/spryker\/propel-orm\/releases\/tag\/1.22.0)\n- [spryker\/util-sanitize:\"^2.3.1\"](https:\/\/github.com\/spryker\/util-sanitize\/releases\/tag\/2.3.1)\n\n### Data import (memory usage)\n\n- [spryker\/acl-entity:\"^1.17.0\"](https:\/\/github.com\/spryker\/acl-entity\/releases\/tag\/1.17.0)\n- [spryker\/data-import:\"^1.33.0\"](https:\/\/github.com\/spryker\/data-import\/releases\/tag\/1.33.0)\n- [spryker\/merchant-relationship-product-list-data-import:\"^0.1.3\"](https:\/\/github.com\/spryker\/merchant-relationship-product-list-data-import\/releases\/tag\/0.1.3)\n- [spryker\/price-product-merchant-relationship-data-import:\"^0.2.5\"](https:\/\/github.com\/spryker\/price-product-merchant-relationship-data-import\/releases\/tag\/0.2.5)\n\n### Cart page and checkout for large carts (100+ items)\n\nFor comprehensive guidance on optimizing cart performance, see [Cart page performance configuration](https:\/\/docs.spryker.com\/docs\/pbc\/all\/cart-and-checkout\/latest\/cart-page-performance-configuration.html).\n\n## Update strategy\n\nTo effectively manage dependency updates:\n\n1. **Monitor release notes**: Regularly check Spryker release notes for performance-related updates.\n2. **Test in staging**: Always test module updates in a staging environment before production deployment.\n3. **Prioritize performance modules**: Focus on modules that directly impact your application's performance bottlenecks.\n4. **Use semantic versioning**: Understand the impact of major, minor, and patch updates.\n5. **Batch related updates**: Group related module updates together for testing efficiency.\n\n## Compatibility considerations\n\nWhen updating modules:\n\n- Check module compatibility with your current Spryker version\n- Review breaking changes in major version updates\n- Test all affected functionality after updates\n- Monitor application performance metrics before and after updates\n- Consider using Spryker's [Composer Dependency Manager](https:\/\/docs.spryker.com\/docs\/scos\/dev\/setup\/managing-scos-dependencies-with-composer.html)\n","pubDate":"Fri, 03 Apr 2026 11:08:16 +0000","link":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/guidelines\/performance-guidelines\/keeping-dependencies-updated.html","guid":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/guidelines\/performance-guidelines\/keeping-dependencies-updated.html"},{"title":"Split publish queues for performance","description":"By default, all publish events are routed through a single generic queue (`PublisherConfig::PUBLISH_QUEUE`). This document explains how to migrate to dedicated per-module queues to improve processing throughput and system stability.\n\n## Benefits\n\nSplitting the publish queue into dedicated per-module queues provides the following benefits:\n\n- **Predictable bulk processing**: Each queue processes a specific type of message, enabling bulk processing instead of random small batches that depend on message arrival order.\n- **Fault isolation**: If one queue becomes stuck, only that specific message type is affected \u2014 not the entire system.\n- **Better resource utilization**: Dedicated queues let you use powerful instances more effectively.\n- **Scalability for all project sizes**: Even small projects benefit from faster and more predictable queue processing.\n\n## Potential issues\n\nSplitting queues can spawn a large number of tasks. To prevent resource exhaustion, configure the maximum number of background processes for both the standard worker and the resource-aware worker in `config\/Shared\/config_default.php`:\n\n```php\n$config[QueueConstants::QUEUE_WORKER_MAX_PROCESSES] = 5;\n```\n\nSet this value according to the resources available on your infrastructure.\n\n{% info_block warningBox \"Worker task limits\" %}\n\nBoth the standard queue worker and the resource-aware queue worker enforce the `QUEUE_WORKER_MAX_PROCESSES` limit on the number of tasks executed in the background. Tune this value carefully based on available CPU and memory.\n\n{% endinfo_block %}\n\n## Install the optimization\n\n```bash\ncomposer update \\\n  spryker\/rabbit-mq:\"^2.23.1\" \\\n  spryker\/category-image-storage:\"^1.9.0\" \\\n  spryker\/cms-page-search:\"^2.10.0\" \\\n  spryker\/cms-storage:\"^2.11.0\" \\\n  spryker\/company-user-storage:\"^1.7.0\" \\\n  spryker\/configurable-bundle-page-search:\"^1.6.0\" \\\n  spryker\/configurable-bundle-storage:\"^2.8.0\" \\\n  spryker\/content-storage:\"^2.8.0\" \\\n  spryker\/customer-access-storage:\"^1.13.0\" \\\n  spryker\/file-manager-storage:\"^2.6.0\" \\\n  spryker\/merchant-product-offer-search:\"^1.8.0\" \\\n  spryker\/navigation-storage:\"^1.14.0\" \\\n  spryker\/price-product-merchant-relationship-storage:\"^1.20.0\" \\\n  spryker\/price-product-offer-storage:\"^1.7.0\" \\\n  spryker\/product-alternative-storage:\"^1.14.0\" \\\n  spryker\/product-category-filter-storage:\"^1.7.0\" \\\n  spryker\/product-discontinued-storage:\"^1.18.0\" \\\n  spryker\/product-group-storage:\"^1.8.0\" \\\n  spryker\/product-list-search:\"^2.10.0\" \\\n  spryker\/product-list-storage:\"^1.20.0\" \\\n  spryker\/product-measurement-unit-storage:\"^1.16.0\" \\\n  spryker\/product-offer-availability-storage:\"^1.5.0\" \\\n  spryker\/product-option-storage:\"^1.16.0\" \\\n  spryker\/product-packaging-unit-storage:\"^5.4.0\" \\\n  spryker\/product-page-search:\"^3.46.0\" \\\n  spryker\/product-quantity-storage:\"^3.7.0\" \\\n  spryker\/product-review-search:\"^1.15.0\" \\\n  spryker\/product-review-storage:\"^1.9.0\" \\\n  spryker\/product-search-config-storage:\"^1.7.0\" \\\n  spryker\/product-set-page-search:\"^1.14.0\" \\\n  spryker\/product-set-storage:\"^1.15.0\" \\\n  spryker\/queue:\"^1.24.0\" \\\n  spryker\/queue-extension:\"^1.2.0\" \\\n  spryker\/shopping-list-storage:\"^1.10.0\" \\\n  spryker\/symfony-messenger:\"^1.2.0\" \\\n  spryker\/tax-product-storage:\"^1.7.0\" \\\n  spryker\/tax-storage:\"^1.7.0\" \\\n  spryker\/url-storage:\"^1.22.0\"\n```\n\nRelease group [SOL-486](https:\/\/api.release.spryker.com\/release-group\/6388)\n\nFor a complete project-level implementation example, see the [B2B Demo Marketplace PR #966](https:\/\/github.com\/spryker-shop\/b2b-demo-marketplace\/pull\/966).\n\n## Configure the dedicated queues\n\nThe migration requires changes in three layers: broker registration, queue processor mapping, and per-module configuration.\n\n### 1. Register queues with the message broker\n\nRegister the dedicated queues with your message broker. Depending on your setup, you configure either `RabbitMqConfig` or `SymfonyMessengerConfig` \u2014 not both. If you use Symfony Messenger, see [Integrate Symfony Messenger](\/docs\/dg\/dev\/integrate-and-configure\/integrate-symfony-messenger.html).\n\n**`src\/Pyz\/Client\/RabbitMq\/RabbitMqConfig.php`**\n\nAdd the following `use` statements and queue constants to `getPublishQueueConfiguration()`:\n\n```php\nuse Spryker\\Shared\\CategoryImageStorage\\CategoryImageStorageConfig;\nuse Spryker\\Shared\\CompanyUserStorage\\CompanyUserStorageConfig;\nuse Spryker\\Shared\\MerchantProductOfferSearch\\MerchantProductOfferSearchConfig;\nuse Spryker\\Shared\\PriceProductMerchantRelationshipStorage\\PriceProductMerchantRelationshipStorageConfig;\nuse Spryker\\Shared\\PriceProductOfferStorage\\PriceProductOfferStorageConfig;\nuse Spryker\\Shared\\ProductAlternativeStorage\\ProductAlternativeStorageConfig;\nuse Spryker\\Shared\\ProductCategoryFilterStorage\\ProductCategoryFilterStorageConfig;\nuse Spryker\\Shared\\ProductDiscontinuedStorage\\ProductDiscontinuedStorageConfig;\nuse Spryker\\Shared\\ProductGroupStorage\\ProductGroupStorageConstants;\nuse Spryker\\Shared\\ProductListSearch\\ProductListSearchConfig;\nuse Spryker\\Shared\\ProductListStorage\\ProductListStorageConfig;\nuse Spryker\\Shared\\ProductMeasurementUnitStorage\\ProductMeasurementUnitStorageConfig;\nuse Spryker\\Shared\\ProductOfferAvailabilityStorage\\ProductOfferAvailabilityStorageConfig;\nuse Spryker\\Shared\\ProductOptionStorage\\ProductOptionStorageConfig;\nuse Spryker\\Shared\\ProductPackagingUnitStorage\\ProductPackagingUnitStorageConfig;\nuse Spryker\\Shared\\ProductQuantityStorage\\ProductQuantityStorageConfig;\nuse Spryker\\Shared\\ProductReviewSearch\\ProductReviewSearchConfig;\nuse Spryker\\Shared\\ProductReviewStorage\\ProductReviewStorageConfig;\nuse Spryker\\Shared\\ProductSearchConfigStorage\\ProductSearchConfigStorageConfig;\nuse Spryker\\Shared\\ProductSetPageSearch\\ProductSetPageSearchConfig;\nuse Spryker\\Shared\\ProductSetStorage\\ProductSetStorageConfig;\nuse Spryker\\Shared\\ShoppingListStorage\\ShoppingListStorageConfig;\nuse Spryker\\Shared\\TaxProductStorage\\TaxProductStorageConfig;\n\n    protected function getPublishQueueConfiguration(): array\n    {\n        return [\n            \/\/ other queue configs\n            CategoryImageStorageConfig::PUBLISH_CATEGORY_IMAGE_QUEUE,\n            CompanyUserStorageConfig::PUBLISH_COMPANY_USER_QUEUE,\n            MerchantProductOfferSearchConfig::PUBLISH_MERCHANT_PRODUCT_OFFER_QUEUE,\n            PriceProductMerchantRelationshipStorageConfig::PUBLISH_PRICE_PRODUCT_MERCHANT_RELATIONSHIP_QUEUE,\n            PriceProductMerchantRelationshipStorageConfig::PUBLISH_PRICE_PRODUCT_CONCRETE_MERCHANT_RELATIONSHIP_QUEUE,\n            PriceProductMerchantRelationshipStorageConfig::PUBLISH_PRICE_PRODUCT_ABSTRACT_MERCHANT_RELATIONSHIP_QUEUE,\n            PriceProductOfferStorageConfig::PUBLISH_PRICE_PRODUCT_OFFER_QUEUE,\n            ProductAlternativeStorageConfig::PUBLISH_PRODUCT_ALTERNATIVE_QUEUE,\n            ProductCategoryFilterStorageConfig::PUBLISH_PRODUCT_CATEGORY_FILTER_QUEUE,\n            ProductDiscontinuedStorageConfig::PUBLISH_PRODUCT_DISCONTINUED_QUEUE,\n            ProductGroupStorageConstants::PUBLISH_PRODUCT_GROUP_QUEUE,\n            ProductListSearchConfig::PUBLISH_PRODUCT_LIST_SEARCH_QUEUE,\n            ProductListStorageConfig::PUBLISH_PRODUCT_LIST_QUEUE,\n            ProductListStorageConfig::PUBLISH_PRODUCT_LIST_PRODUCT_ABSTRACT_QUEUE,\n            ProductListStorageConfig::PUBLISH_PRODUCT_LIST_PRODUCT_CONCRETE_QUEUE,\n            ProductOfferAvailabilityStorageConfig::PUBLISH_PRODUCT_OFFER_AVAILABILITY_QUEUE,\n            ProductOptionStorageConfig::PUBLISH_PRODUCT_OPTION_QUEUE,\n            ProductQuantityStorageConfig::PUBLISH_PRODUCT_QUANTITY_QUEUE,\n            ProductReviewSearchConfig::PUBLISH_PRODUCT_REVIEW_QUEUE,\n            ProductReviewStorageConfig::PUBLISH_PRODUCT_REVIEW_STORAGE_QUEUE,\n            ProductSearchConfigStorageConfig::PUBLISH_PRODUCT_SEARCH_CONFIG_QUEUE,\n            ProductSetPageSearchConfig::PUBLISH_PRODUCT_SET_PAGE_QUEUE,\n            ProductSetStorageConfig::PUBLISH_PRODUCT_SET_QUEUE,\n            ShoppingListStorageConfig::PUBLISH_SHOPPING_LIST_QUEUE,\n            TaxProductStorageConfig::PUBLISH_TAX_PRODUCT_QUEUE,\n            ProductMeasurementUnitStorageConfig::PUBLISH_PRODUCT_MEASUREMENT_UNIT_QUEUE,\n            ProductPackagingUnitStorageConfig::PUBLISH_PRODUCT_PACKAGING_UNIT_QUEUE,\n        ];\n    }\n```\n\nIf you use Symfony Messenger instead of RabbitMQ, apply the same changes to `src\/Pyz\/Client\/SymfonyMessenger\/SymfonyMessengerConfig.php`.\n\n### 2. Map queues to processor plugins\n\nUpdate `QueueDependencyProvider` to map each new queue to its processor plugin.\n\n**`src\/Pyz\/Zed\/Queue\/QueueDependencyProvider.php`**\n\nFor each dedicated queue, add a mapping to either `SynchronizationStorageQueueMessageProcessorPlugin` (for storage queues) or `SynchronizationSearchQueueMessageProcessorPlugin` (for search queues). For example:\n\n```php\nCategoryImageStorageConfig::PUBLISH_CATEGORY_IMAGE_QUEUE => [\n    new SynchronizationStorageQueueMessageProcessorPlugin(),\n],\nProductReviewSearchConfig::PUBLISH_PRODUCT_REVIEW_QUEUE => [\n    new SynchronizationSearchQueueMessageProcessorPlugin(),\n],\n\/\/ ... repeat for all dedicated queues\n```\n\n### 3. Update per-module Zed configuration\n\nFor each module, override the config class at the project level to return the module-specific queue constant instead of the generic `PublisherConfig::PUBLISH_QUEUE`.\n\nThe following table lists the files to update and their corresponding queue constants:\n\n| File | Queue constant |\n|---|---|\n| `src\/Pyz\/Zed\/CategoryImageStorage\/CategoryImageStorageConfig.php` | `CategoryImageStorageConfig::PUBLISH_CATEGORY_IMAGE_QUEUE` |\n| `src\/Pyz\/Zed\/CompanyUserStorage\/CompanyUserStorageConfig.php` | `CompanyUserStorageConfig::PUBLISH_COMPANY_USER_QUEUE` |\n| `src\/Pyz\/Zed\/MerchantProductOfferSearch\/MerchantProductOfferSearchConfig.php` | `MerchantProductOfferSearchConfig::PUBLISH_MERCHANT_PRODUCT_OFFER_QUEUE` |\n| `src\/Pyz\/Zed\/PriceProductMerchantRelationshipStorage\/PriceProductMerchantRelationshipStorageConfig.php` | `PUBLISH_PRICE_PRODUCT_MERCHANT_RELATIONSHIP_QUEUE`, `PUBLISH_PRICE_PRODUCT_CONCRETE_MERCHANT_RELATIONSHIP_QUEUE`, `PUBLISH_PRICE_PRODUCT_ABSTRACT_MERCHANT_RELATIONSHIP_QUEUE` |\n| `src\/Pyz\/Zed\/PriceProductOfferStorage\/PriceProductOfferStorageConfig.php` | `PriceProductOfferStorageConfig::PUBLISH_PRICE_PRODUCT_OFFER_QUEUE` |\n| `src\/Pyz\/Zed\/ProductAlternativeStorage\/ProductAlternativeStorageConfig.php` | `ProductAlternativeStorageConfig::PUBLISH_PRODUCT_ALTERNATIVE_QUEUE` |\n| `src\/Pyz\/Zed\/ProductCategoryFilterStorage\/ProductCategoryFilterStorageConfig.php` | `ProductCategoryFilterStorageConfig::PUBLISH_PRODUCT_CATEGORY_FILTER_QUEUE` |\n| `src\/Pyz\/Zed\/ProductDiscontinuedStorage\/ProductDiscontinuedStorageConfig.php` | `ProductDiscontinuedStorageConfig::PUBLISH_PRODUCT_DISCONTINUED_QUEUE` |\n| `src\/Pyz\/Zed\/ProductGroupStorage\/ProductGroupStorageConfig.php` | `ProductGroupStorageConstants::PUBLISH_PRODUCT_GROUP_QUEUE` |\n| `src\/Pyz\/Zed\/ProductListSearch\/ProductListSearchConfig.php` | `ProductListSearchConfig::PUBLISH_PRODUCT_LIST_SEARCH_QUEUE` |\n| `src\/Pyz\/Zed\/ProductListStorage\/ProductListStorageConfig.php` | `PUBLISH_PRODUCT_LIST_QUEUE`, `PUBLISH_PRODUCT_LIST_PRODUCT_ABSTRACT_QUEUE`, `PUBLISH_PRODUCT_LIST_PRODUCT_CONCRETE_QUEUE` |\n| `src\/Pyz\/Zed\/ProductMeasurementUnitStorage\/ProductMeasurementUnitStorageConfig.php` | `ProductMeasurementUnitStorageConfig::PUBLISH_PRODUCT_MEASUREMENT_UNIT_QUEUE` |\n| `src\/Pyz\/Zed\/ProductOfferAvailabilityStorage\/ProductOfferAvailabilityStorageConfig.php` | `ProductOfferAvailabilityStorageConfig::PUBLISH_PRODUCT_OFFER_AVAILABILITY_QUEUE` |\n| `src\/Pyz\/Zed\/ProductOptionStorage\/ProductOptionStorageConfig.php` | `ProductOptionStorageConfig::PUBLISH_PRODUCT_OPTION_QUEUE` |\n| `src\/Pyz\/Zed\/ProductPackagingUnitStorage\/ProductPackagingUnitStorageConfig.php` | `ProductPackagingUnitStorageConfig::PUBLISH_PRODUCT_PACKAGING_UNIT_QUEUE` |\n| `src\/Pyz\/Zed\/ProductQuantityStorage\/ProductQuantityStorageConfig.php` | `ProductQuantityStorageConfig::PUBLISH_PRODUCT_QUANTITY_QUEUE` |\n| `src\/Pyz\/Zed\/ProductReviewSearch\/ProductReviewSearchConfig.php` | `ProductReviewSearchConfig::PUBLISH_PRODUCT_REVIEW_QUEUE` |\n| `src\/Pyz\/Zed\/ProductReviewStorage\/ProductReviewStorageConfig.php` | `ProductReviewStorageConfig::PUBLISH_PRODUCT_REVIEW_STORAGE_QUEUE` |\n| `src\/Pyz\/Zed\/ProductSearchConfigStorage\/ProductSearchConfigStorageConfig.php` | `ProductSearchConfigStorageConfig::PUBLISH_PRODUCT_SEARCH_CONFIG_QUEUE` |\n| `src\/Pyz\/Zed\/ProductSetPageSearch\/ProductSetPageSearchConfig.php` | `ProductSetPageSearchConfig::PUBLISH_PRODUCT_SET_PAGE_QUEUE` |\n| `src\/Pyz\/Zed\/ProductSetStorage\/ProductSetStorageConfig.php` | `ProductSetStorageConfig::PUBLISH_PRODUCT_SET_QUEUE` |\n| `src\/Pyz\/Zed\/ShoppingListStorage\/ShoppingListStorageConfig.php` | `ShoppingListStorageConfig::PUBLISH_SHOPPING_LIST_QUEUE` |\n| `src\/Pyz\/Zed\/TaxProductStorage\/TaxProductStorageConfig.php` | `TaxProductStorageConfig::PUBLISH_TAX_PRODUCT_QUEUE` |\n\nEach file follows the same pattern:\n\n```php\n\/\/ Before:\nuse Spryker\\Shared\\Publisher\\PublisherConfig;\n\npublic function getQueueName(): string\n{\n    return PublisherConfig::PUBLISH_QUEUE;\n}\n\n\/\/ After (example for CategoryImageStorage):\nuse Spryker\\Shared\\CategoryImageStorage\\CategoryImageStorageConfig as SprykerSharedCategoryImageStorageConfig;\n\npublic function getQueueName(): string\n{\n    return SprykerSharedCategoryImageStorageConfig::PUBLISH_CATEGORY_IMAGE_QUEUE;\n}\n```\n\n### 4. Create the new queues in the broker\n\nAfter completing all configuration changes, execute the following command to create the new queues in your message broker:\n\n```bash\nvendor\/bin\/console queue:setup\n```\n\n## Related documentation\n\n- [Configure event queues](\/docs\/dg\/dev\/backend-development\/data-manipulation\/event\/configure-event-queues.html)\n- [Optimizing Jenkins execution with the resource-aware queue worker](\/docs\/dg\/dev\/backend-development\/cronjobs\/optimizing-jenkins-execution.html)\n","pubDate":"Fri, 03 Apr 2026 07:55:48 +0000","link":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/guidelines\/performance-guidelines\/split-queues-performance.html","guid":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/guidelines\/performance-guidelines\/split-queues-performance.html"},{"title":"Using the Support Hub","description":"This document describes how to use the support hub to create and manage your tickets.\n\n## Prerequisites\n\n- Log in at the [Spryker Portal](https:\/\/portal.spryker.com). If you don't have access to the Spryker Portal, request it using [this form](https:\/\/portal.spryker.com\/request-access).\n- Go the the Support Hub, using the squares menu in the top right.\n\n## Create a new ticket\n\nTo create a new ticket, click **Create a ticket** and follow the wizard.\n\nWhen creating a ticket, use the recommendations in [Share secrets with the Spryker Support team](\/docs\/about\/all\/support\/share-secrets-with-the-spryker-support-team.html).\n\n\nThe following are the top-level categories of tickets and their description.\n\n### Report a Problem or Incident\n\nProblems can be reports suspecting a bug or issues with the hosting services. To speed up the resolution of such tickets, make sure to follow [Getting the most out of Spryker support](\/docs\/about\/all\/support\/getting-the-most-out-of-spryker-support.html) before you submit your request.\n\n### Ask a Question\n\nFor any questions about Spryker. We want the knowledge about Spryker to be available to everyone. So, we'll provide you with a link to [Spryker Community](https:\/\/commercequest.space\/) to ask your question there. If there are docs on the topic, we will provide a link to that.\n\n### Infrastructure Change Request and Access Management\n\nRequest all currently supported standard changes, such as requesting changes to non-production environments sizing, IAM users and environment provisioning.\n\n### Reporting a Problem with Spryker CI\n\nReport an issue with Spryker CI (Buddy), such as errors or issues with its UI or pipeline runs.\n\n### Announce a Go Live\n\nInform the Customer Success Team about being close to go live.\n\n### Request Help with Spryker ACP\n\nReport an issue with an Spryker ACP connector.\n\n### Request Professional Services\n\nThis category offers a selection of professional services we are offering. For example, you may need it when implementing a complex custom feature.\n\n### Request Help with Spryker Code Upgrader\n\nRequest help with the Upgrader. These requests are processed by our Upgrader experts.\n\n### Announce High Traffic\/Load\n\nLet us know about events or time periods in which you expect a higher than usual load on your production enviornments. We can use this information to check auto scaling settings and evaluate if they need to be adjusted to meet your demands.\n\n### Emergencies\n\nEmergencies are reserved for problems that have significant business impact now or very soon. Emergency tickets regularly start an [escalation](\/docs\/about\/all\/support\/support-case-escalations.html). This category shouldn't be used to speed up requests or problem reports. Emergencies need to be associated with significant risk or business impact, like revenue, security, or go-lives.\n\n### Info on Change Requests\n\n{% info_block warningBox \"Plan your change requests and use the right request form\" %}\n\nBecause of verification processes and role-based access control mechanisms, change requests take some time to process. Expect 3-5 days of processing time.\n\nBecause of contractual reasons, only customers can request new environments or access to environment monitoring, not partners.\n\n{% endinfo_block %}\n\n## Manage tickets\n\nClicking on **View tickets** opens the list of tickets your organisation has opened. To view the details of a particular ticket, click on the \"Details\" button. Here you can take a look at the communication history, view the status of the ticket and associated Jira ticket, and inspect the assigned priority.\n\n### Ticket receipts and notifications\n\nWhen creating a ticket, or when there are meaningful updates to your ticket, like a status change or new comments, you will receive email notifications. Notifications are sent to the email address associated with the Spryker Portal account that was used to create a ticket.\n\nIf you are managing multiple projects or have a high volume of tickets and communication with us, knowing the structure of our notifications and receipts can help you prepare forwarding or labelling rules in your email client:\n\n\n- Ticket confirmation emails are sent when you create a ticket or when its status is updated. Subject pattern:\n\n```bash\nCase Receipt - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME} - Status: {STATUS}. {TRACKING ID}\n```\n\n- Change request confirmation emails are sent when you create a change request. Subject pattern:\n\n```bash\nChange Request Receipt - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME} - Status: {STATUS}. {TRACKING ID}\n```\n\n- ETA update notification emails are sent when the ETA on your ticket is updated. Subject pattern:\n\n```bash\nCase ETA Update - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME}} - ETA: {ETA}. {TRACKING ID}\n```\n\n- Emergency ticket emails are sent when you declare an emergency or your emergency ticket's status is updated. Subject pattern:\n\n```bash\nEmergency {STATUS} - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME} {TRACKING ID}\n```\n\n- Ticket comment notification emails are sent when there is a new comment in your ticket. Subject pattern:\n\n```bash\nCase Comment Notification - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME} - Status: {STATUS} {Tracking ID}\n```\n","pubDate":"Fri, 03 Apr 2026 07:30:45 +0000","link":"https:\/\/docs.spryker.com\/docs\/about\/all\/support\/using-the-support-portal.html","guid":"https:\/\/docs.spryker.com\/docs\/about\/all\/support\/using-the-support-portal.html"},{"title":"User management (IAM)","description":"The **User management (IAM Users)** panel in [CloudHub](\/docs\/ca\/dev\/cloud-hub\/cloud-hub.html) lets you control infrastructure access and define how team members connect to your environments. You can create, update, and delete IAM users directly through the portal.\n\n## Capabilities\n\n- **Identity provisioning:** Create IAM users for specific environments to ensure precise access control.\n- **Secure connectivity:** Enable or disable VPN access for individual users to secure communications with protected network resources.\n- **Authentication configuration:** Manage SSH public keys for users, enabling secure, key-based authentication for terminal and remote access.\n- **User lifecycle management:** Modify existing user configurations or remove user when it is no longer required.\n\n## Credential delivery for new users\n\nWhen a new IAM user is created, credentials and access configuration are delivered securely across three separate emails:\n\n1. **Password email:** The user's password is delivered via the [OneTimeSecret](https:\/\/onetimesecret.com) service as a one-time link. The link is protected by a passphrase, so the password cannot be accessed without it.\n2. **Passphrase email:** The passphrase required to open the OneTimeSecret link is sent in a separate email. You must have both emails to retrieve the password.\n3. **VPN configuration email:** The VPN configuration file (OVPN profile) required to connect to the protected network is sent in a third separate email.\n\n{% info_block infoBox \"Security note\" %}\n\nKeep all three emails secure. The OneTimeSecret link can only be opened once\u2014if it has already been accessed, request a new user setup through CloudHub.\n\n{% endinfo_block %}\n","pubDate":"Fri, 03 Apr 2026 07:01:37 +0000","link":"https:\/\/docs.spryker.com\/docs\/ca\/dev\/cloud-hub\/user-management.html","guid":"https:\/\/docs.spryker.com\/docs\/ca\/dev\/cloud-hub\/user-management.html"},{"title":"Maintenance","description":"The **Maintenance** panel in [CloudHub](\/docs\/ca\/dev\/cloud-hub\/cloud-hub.html) serves as the communication hub for infrastructure stability and scheduled updates. You will be notified about maintenance operations that are to be executed on your environments. \n\n## Capabilities\n\n- **Operational transparency:** Stay informed about upcoming maintenance windows and infrastructure changes that may affect environment availability.\n- **Proactive planning:** Review scheduled tasks to coordinate deployments and business activities around system updates, minimizing potential downtime.\n- **Reschedule maintenance slot:** Create ticket for our operations team to reschedule maintenance slot.\n","pubDate":"Fri, 03 Apr 2026 06:57:30 +0000","link":"https:\/\/docs.spryker.com\/docs\/ca\/dev\/cloud-hub\/maintenance.html","guid":"https:\/\/docs.spryker.com\/docs\/ca\/dev\/cloud-hub\/maintenance.html"},{"title":"Performance guidelines","description":"These performance guidelines originate from Spryker's years of experience across all kinds of projects, environments, and setups. They cover topics that are often missed at the project level, leading to poor performance or other related issues. The guidelines help you analyze and optimize performance of your website from different perspectives:\n\n- [Keeping dependencies updated](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/keeping-dependencies-updated.html) to maintain optimal performance and security by staying current with Spryker module updates.\n- [Monitoring](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/monitoring.html) to ensure effective application monitoring using APM tools.\n- [General performance guidelines](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/general-performance-guidelines.html) for general approaches to optimizing the server-side execution time.\n- [Architecture performance guidelines](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/architecture-performance-guidelines.html) to optimize performance in the very end servers.\n- [Frontend performance guidelines](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/front-end-performance-guidelines.html) to do the frontend-specific optimization.\n- [Twig performance best practices](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/twig-performance-best-practices.html) to optimize Twig templating engine performance.\n- [Session locks](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/session-locks.html) to optimize session locking mechanisms and reduce performance impact. Also see [Redis session lock](\/docs\/dg\/dev\/troubleshooting\/troubleshooting-performance-issues\/redis-session-lock.html) for troubleshooting session lock issues.\n- [Bot control](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/bot-control.html) to manage honest and malicious bot traffic effectively.\n- [Batch processing of Propel entities](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/performance-guidelines-batch-processing-propel-entities.html) for efficient batch processing, reduced database load, and support for complex entity relationships.\n- [Database performance guidelines](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/database-performance-guidelines.html) to optimize database operations through proper indexing, query optimization, and avoiding common database anti-patterns.\n- [Key-Value storage performance guidelines](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/key-value-storage-performance-guidelines.html) to optimize Redis\/ValKey usage by limiting operations, avoiding admin commands in runtime, and implementing proper caching strategies.\n- [External HTTP requests](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/external-http-requests.html) to understand Spryker's architecture principle of reading from fast storage and learn how to manage external HTTP requests when they're necessary.\n- [Search performance guidelines](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/search-performance-guidelines.html) to optimize Elasticsearch and OpenSearch performance, avoid common search anti-patterns, and implement efficient search queries.\n- [Infrastructure and worker configuration guidelines](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/infrastructure-worker-configuration-guidelines.html) to optimize nginx configuration and worker orchestration for multi-store setups.\n- [CDN and traffic management integration](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/cdn-and-traffic-management-integration.html) to configure CDN solutions like Akamai or Cloudflare to work correctly with Spryker's nginx compression and avoid unnecessary data transfer overhead.\n- [Split publish queues for performance](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/split-queues-performance.html) to migrate from a single generic publish queue to dedicated per-module queues for improved throughput, fault isolation, and resource utilization.\n- [Custom code performance guidelines](\/docs\/dg\/dev\/guidelines\/performance-guidelines\/custom-code-performance-guidelines.html) to implement performant custom code including caching strategies, background processing, and Quote calculator optimization.\n- [Common pitfalls in OMS design](\/docs\/pbc\/all\/order-management-system\/latest\/base-shop\/datapayload-conversion\/state-machine\/common-pitfalls-in-oms-design.html) to avoid performance bottlenecks in Order Management System processes, especially ensuring heavy operations run in CLI context rather than during web requests.\n- [Order management system multi-thread](\/docs\/pbc\/all\/order-management-system\/latest\/base-shop\/datapayload-conversion\/state-machine\/order-management-system-multi-thread.html) to process OMS timeouts and conditions in parallel for improved order processing performance.\n- [Troubleshooting performance issues](\/docs\/dg\/dev\/troubleshooting\/troubleshooting-performance-issues\/troubleshooting-performance-issues.html) for detecting and fixing common performance problems.\n- [Order details page performance guidance](\/docs\/pbc\/all\/order-management-system\/latest\/base-shop\/order-management-feature-overview\/order-details-page-performance-overview.html) to optimize the order detail page in the Back Office\n","pubDate":"Fri, 03 Apr 2026 06:54:22 +0000","link":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/guidelines\/performance-guidelines\/performance-guidelines.html","guid":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/guidelines\/performance-guidelines\/performance-guidelines.html"},{"title":"CloudHub","description":"<p>CloudHub is a centralized self-service portal that lets you manage your Spryker infrastructure directly, without raising manual support requests for routine tasks. It provides a streamlined interface for provisioning resources and managing access.<\/p>\n<p>Technical teams can use CloudHub to maintain a clear overview of their cloud assets and keep access and storage resources aligned across environments, such as staging and production.<\/p>\n<p>CloudHub includes the following panels:<\/p>\n<ul>\n<li><a href=\"\/docs\/ca\/dev\/cloud-hub\/user-management.html\">User management (IAM)<\/a>: Provision and manage IAM users, configure VPN access, and manage SSH public keys.<\/li>\n<li><a href=\"\/docs\/ca\/dev\/cloud-hub\/storage-management.html\">Storage management (S3)<\/a>: Provision and manage S3 buckets across your environments.<\/li>\n<li><a href=\"\/docs\/ca\/dev\/cloud-hub\/maintenance.html\">Maintenance<\/a>: View upcoming maintenance windows and scheduled infrastructure updates.<\/li>\n<\/ul>\n<h2 id=\"resource-status-and-validation\">Resource status and validation<\/h2>\n<p>CloudHub provides feedback on all infrastructure actions through the <strong>Processing Status<\/strong> column. This ensures transparency during the asynchronous provisioning process.<\/p>\n<table>\n<thead>\n<tr>\n<th align=\"left\">Status<\/th>\n<th align=\"left\">Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td align=\"left\"><strong>In Progress<\/strong><\/td>\n<td align=\"left\">The infrastructure change is currently being deployed or updated by the automation engine.<\/td>\n<\/tr>\n<tr>\n<td align=\"left\"><strong>Error<\/strong><\/td>\n<td align=\"left\">The action could not be completed. CloudHub provides specific error details. There are two types of error user might face:<br>\u2022 <strong>System errors<\/strong>: In this case, we create a HubSpot ticket for our operations team to handle the problem. The user will receive a ticket number to track progress.<br>\u2022 <strong>Validation errors<\/strong>: Issues like \u201cS3 bucket name already exists\u201d which must be fixed by the user.<\/td>\n<\/tr>\n<tr>\n<td align=\"left\"><strong>Active\/Success<\/strong><\/td>\n<td align=\"left\">The resource is fully provisioned, validated, and ready for use in the designated environment.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","pubDate":"Fri, 03 Apr 2026 06:51:59 +0000","link":"https:\/\/docs.spryker.com\/docs\/ca\/dev\/cloud-hub\/cloud-hub.html","guid":"https:\/\/docs.spryker.com\/docs\/ca\/dev\/cloud-hub\/cloud-hub.html"},{"title":"Storage management (S3)","description":"The **Storage management (S3)** panel in [CloudHub](\/docs\/ca\/dev\/cloud-hub\/cloud-hub.html) provides a simplified workflow for handling object storage requirements across your infrastructure. You can create and update S3 buckets directly through the portal.\n\n## Capabilities\n\n- **On-demand bucket creation:** Provision new S3 buckets for any integrated environment.\n- **Access policy control:** Define data visibility at the point of creation. You can set buckets to **Private** (restricted) or **Public** (accessible via the internet) based on your security requirements.\n- **Asset inventory:** Maintain a high-level view of all storage assets, including their associated environments, access levels, and creation dates.\n- **Resource management:** Update bucket settings directly through the portal.\n\n## Bucket lifecycle management\n\nYou can create and update S3 buckets through CloudHub. Bucket deletion is not available through the portal due to security constraints\u2014this prevents accidental removal of storage resources that may contain critical data.\n\n{% info_block infoBox \"Bucket removal\" %}\n\nIf you need to delete an S3 bucket, create an Infrastructure Change Request in the [Support Portal](https:\/\/support.spryker.com).\n\n{% endinfo_block %}\n","pubDate":"Thu, 02 Apr 2026 20:06:51 +0000","link":"https:\/\/docs.spryker.com\/docs\/ca\/dev\/cloud-hub\/storage-management.html","guid":"https:\/\/docs.spryker.com\/docs\/ca\/dev\/cloud-hub\/storage-management.html"},{"title":"AI IDE assistants","description":"<p>This document describes the AI IDE Assistants you can use when developing your Spryker projects. You will read about recommended AI IDE Assistants, how to set up and use them.<\/p>\n<p>Here are some examples of how you can use AI assistants in your work:<\/p>\n<ul>\n<li>Generate a code completion suggestion<\/li>\n<li>Describe a code fragment<\/li>\n<li>Generate a doc block for a code fragment<\/li>\n<li>Fix syntax bugs in a code fragment<\/li>\n<li>Simplify a code fragment<\/li>\n<li>Generate tests for a code fragment<\/li>\n<li>IO interactions<\/li>\n<li>Code generation<\/li>\n<\/ul>\n<section class='info-block info-block--warning'><i class='info-block__icon icon-warning'><\/i><div class='info-block__content'>\n<p>Before using AI tools, consult with your legal department.<\/p>\n<\/div><\/section>\n<h2 id=\"install-ai-assistants\">Install AI assistants<\/h2>\n<p>We recommend trying the following assistants:<\/p>\n<ul>\n<li>GitHub Copilot<\/li>\n<li>Qodo (formerly Codium)<\/li>\n<li>Cursor<\/li>\n<\/ul>\n<h3 id=\"install-github-copilot\">Install GitHub Copilot<\/h3>\n<p>GitHub Copilot is an AI pair programmer that helps you write code faster. It draws context from comments and code and suggests individual lines and whole functions instantly.\nTo start using GitHub Copilot, do the following:<\/p>\n<ol>\n<li>Install the <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/17718-github-copilot\">GitHub Copilot extension<\/a> in your IDE.<\/li>\n<li>Authorize yourself as a GitHub user in <strong>Preferences<\/strong> &gt; <strong>Languages and Frameworks<\/strong> &gt; <strong>GitHub Copilot<\/strong>.<\/li>\n<\/ol>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/github-copilot-config.png\" alt=\"github-copilot-config\" \/><\/p>\n<p>Now you can use the GitHub Copilot.<\/p>\n<h3 id=\"install-qodo\">Install Qodo<\/h3>\n<p>Qodo is an AI-powered tool that helps developers to generate code, tests, and docs.\nTo set up Qodo, install the <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/21206-qodo-gen-formerly-codiumate-\">Qodo Gen plugin<\/a>. If the installation is successful, you can see Codiumate in the context menu.<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/qodo-menu.png\" alt=\"qodo-menu\" \/><\/p>\n<h3 id=\"install-cursor\">Install Cursor<\/h3>\n<p>Cursor is an AI powered IDE forked from VS Code. To set up Cursor, follow the steps:<\/p>\n<ol>\n<li>Download Cursor from its <a href=\"https:\/\/www.cursor.com\/\">official website<\/a>.<\/li>\n<li>Install Cursor from the downloaded file.<\/li>\n<li>Optional: To save your work, enable autosave files in the settings.<\/li>\n<\/ol>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/cursor-autosave.png\" alt=\"cursor-autosave\" \/><\/p>\n<h2 id=\"using-github-copilot\">Using GitHub Copilot<\/h2>\n<p>Most features of GitHub Copilot can be used as follows:<\/p>\n<ol>\n<li>Highlight a code fragment to process.<\/li>\n<li>Right-click to open the context menu.<\/li>\n<li>In the context menu, hover over <strong>GitHub Copilot<\/strong> and click the needed option.<\/li>\n<\/ol>\n<p>Generate suggestions based on the existing code in your project:<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/github-copilot-suggestion.png\" alt=\"github-copilot-suggestion\" \/><\/p>\n<p>Explain a code fragment:<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/github-copilot-description.png\" alt=\"github-copilot-description\" \/><\/p>\n<p>Generate doc blocks and add comments:<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/github-copilot-generate-docs.png\" alt=\"github-copilot-generate-docs\" \/><\/p>\n<p>Generate suggestions for fixing syntax bugs:<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/github-copilot-fix-syntax-bugs.png\" alt=\"github-copilot-fix-syntax-bugs\" \/><\/p>\n<p>Refactor a code fragment:<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/github-copilot-refactor-code.png\" alt=\"github-copilot-refactor-code\" \/><\/p>\n<p>Generate tests:<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/github-copilot-generate-tests.png\" alt=\"github-copilot-generate-tests\" \/><\/p>\n<p>Interact with GitHub Copilot using prompts:<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/github-copilot-io-interaction.png\" alt=\"github-copilot-io-interaction\" \/><\/p>\n<h2 id=\"generating-tests-using-qodo\">Generating tests using Qodo<\/h2>\n<p>When it comes to generating tests, Qodo offers a more flexible configuration and a wider range of test scenarios compared to GitHub Copilot. Here\u2019s an example of tests generated with Qodo:<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/quodo-generate-tests.png\" alt=\"quodo-generate-tests\" \/><\/p>\n<h2 id=\"code-generation-using-cursor\">Code generation using Cursor<\/h2>\n<p>Cursor AI offers context-aware suggestions by considering the bigger picture within the codebase. This enables it to deliver more accurate and well-structured recommendations, in contrast to GitHub Copilot, which mainly focuses on real-time suggestions based on the specific line of code you\u2019re working on. It\u2019s great at generating basic code and significantly saves time, especially when you need to create something from scratch.<\/p>\n<p>Here\u2019s an example of code generated with Cursor:<\/p>\n<p><img src=\"https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-coding-assistants.md\/cursor-generate-code.png\" alt=\"cursor-generate-code\" \/><\/p>\n<h2 id=\"ai-ide-assistants\">AI IDE assistants<\/h2>\n<ul>\n<li><a href=\"\/docs\/dg\/dev\/ai\/ai-assistants\/spryker-engineer-gpt\">Spryker Engineer GPT<\/a><\/li>\n<li><a href=\"\/docs\/dg\/dev\/ai\/ai-assistants\/spryker-k6-performance-assistant-gpt\">Spryker K6 Performance Assistant GPT<\/a>: Assists with generating K6 performance test scripts from provided API endpoints<\/li>\n<li><a href=\"\/docs\/dg\/dev\/ai\/ai-assistants\/spryker-devqa-assistant-gpt\">Spryker DevQA Assistant GPT<\/a>: Assists in DevQA tasks by providing comprehensive QA checklists and insights into feature and module mappings and dependencies<\/li>\n<li><a href=\"\/docs\/dg\/dev\/ai\/ai-assistants\/spryker-cypress-e2e-assistant-gpt\">Spryker Cypress E2E Assistant GPT<\/a><\/li>\n<\/ul>\n","pubDate":"Wed, 01 Apr 2026 18:12:39 +0000","link":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/ai\/ai-assistants\/ai-ide-assistants.html","guid":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/ai\/ai-assistants\/ai-ide-assistants.html"},{"title":"Install Back Office Assistant","description":"Back Office Assistant is an AI-powered chat widget embedded in the Back Office. It lets admin users ask natural language questions, navigate the Back Office, manage orders, and create or update discounts through a conversational interface. This document describes how to install the Back Office Assistant feature.\n\n## Install the feature core\n\nFollow the steps in the following sections to install the Back Office Assistant feature core.\n\n### Prerequisites\n\nInstall the required features:\n\n| NAME | VERSION | INSTALLATION GUIDE |\n|------|---------|-------------------|\n| AI Commerce | {{page.release_tag}} | [Install AI Commerce](\/docs\/dg\/dev\/ai\/ai-commerce\/install-ai-commerce.html) |\n\n### 1) Install the required modules\n\n```bash\ncomposer require spryker-feature\/ai-commerce\n```\n\n### 2) Generate transfers and run database migration\n\n```bash\nconsole transfer:generate\nconsole propel:install\n```\n\n### 3) Configure AI models for Back Office Assistant\n\nThe Back Office Assistant uses a dedicated named AI configuration for each agent. Add these configuration entries to `config\/Shared\/config_ai.php`:\n\n`config\/Shared\/config_ai.php`\n\n```php\n<?php\n\nuse Spryker\\Shared\\AiFoundation\\AiFoundationConstants;\nuse SprykerFeature\\Shared\\AiCommerce\\AiCommerceConstants;\n\n$openAiConfiguration = [\n    'provider_name' => AiFoundationConstants::PROVIDER_OPENAI,\n    'provider_config' => [\n        'key' => getenv('OPEN_AI_API_TOKEN') ?: '',\n        'model' => 'gpt-4o-mini', \/\/ fastest non-reasoning model\n    ],\n];\n\n$config[AiFoundationConstants::AI_CONFIGURATIONS] = [\n    AiFoundationConstants::AI_CONFIGURATION_DEFAULT => $openAiConfiguration,\n    AiCommerceConstants::AI_CONFIGURATION_INTENT_ROUTER => $openAiConfiguration,\n    AiCommerceConstants::AI_CONFIGURATION_GENERAL_PURPOSE => array_merge($openAiConfiguration, [\n        'system_prompt' => AiFoundationConstants::CONFIGURATION_REFERENCE_PREFIX . AiCommerceConstants::CONFIGURATION_KEY_GENERAL_PURPOSE_SYSTEM_PROMPT,\n        'provider_config' => array_merge($openAiConfiguration['provider_config'], [\n            'model' => 'gpt-4.1', \/\/ fast non-reasoning model\n        ]),\n    ]),\n    AiCommerceConstants::AI_CONFIGURATION_ORDER_MANAGEMENT => array_merge($openAiConfiguration, [\n        'system_prompt' => AiFoundationConstants::CONFIGURATION_REFERENCE_PREFIX . AiCommerceConstants::CONFIGURATION_KEY_ORDER_MANAGEMENT_SYSTEM_PROMPT,\n        'provider_config' => array_merge($openAiConfiguration['provider_config'], [\n            'model' => 'gpt-4.1', \/\/ fast non-reasoning model\n        ]),\n    ]),\n    AiCommerceConstants::AI_CONFIGURATION_DISCOUNT_MANAGEMENT => array_merge($openAiConfiguration, [\n        'system_prompt' => AiFoundationConstants::CONFIGURATION_REFERENCE_PREFIX . AiCommerceConstants::CONFIGURATION_KEY_DISCOUNT_MANAGEMENT_SYSTEM_PROMPT,\n        'provider_config' => array_merge($openAiConfiguration['provider_config'], [\n            'model' => 'gpt-4.1', \/\/ fast non-reasoning model\n        ]),\n    ]),\n];\n```\n\nUsing a dedicated AI model configuration per agent is recommended because each named configuration is tracked separately in the AiFoundation audit log. This lets you isolate and review all AI calls made by each agent independently from other AI features in your project.\n\n### 4) Set up behavior\n\nRegister the following plugins to integrate the Back Office Assistant agents:\n\n| PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |\n|--------|---------------|---------------|-----------|\n| `GeneralPurposeAgentPlugin` | Registers the General Purpose agent that answers Back Office navigation and how-to questions. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\Agent` |\n| `OrderManagementAgentPlugin` | Registers the Order Management agent that provides read-only access to order and OMS data. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\Agent` |\n| `DiscountManagementAgentPlugin` | Registers the Discount Management agent that can create and update discounts. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\Agent` |\n\n**src\/Pyz\/Zed\/AiCommerce\/AiCommerceDependencyProvider.php**\n\n```php\n<?php\n\nnamespace Pyz\\Zed\\AiCommerce;\n\nuse SprykerFeature\\Zed\\AiCommerce\\AiCommerceDependencyProvider as SprykerFeatureAiCommerceDependencyProvider;\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\Agent\\DiscountManagementAgentPlugin;\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\Agent\\GeneralPurposeAgentPlugin;\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\Agent\\OrderManagementAgentPlugin;\n\nclass AiCommerceDependencyProvider extends SprykerFeatureAiCommerceDependencyProvider\n{\n    \/**\n     * @return array<\\SprykerFeature\\Zed\\AiCommerce\\Dependency\\BackofficeAssistant\\BackofficeAssistantAgentPluginInterface>\n     *\/\n    protected function getBackofficeAssistantAgentPlugins(): array\n    {\n        return [\n            new GeneralPurposeAgentPlugin(),\n            new OrderManagementAgentPlugin(),\n            new DiscountManagementAgentPlugin(),\n        ];\n    }\n}\n```\n\nRegister the following plugins in `AiFoundationDependencyProvider`:\n\n| PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |\n|--------|---------------|---------------|-----------|\n| `BackofficeAssistantSsePreToolCallPlugin` | Streams a Server-Sent Event to the browser before each tool call. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation` |\n| `BackofficeAssistantSsePostToolCallPlugin` | Streams a Server-Sent Event to the browser after each tool call. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation` |\n| `AuditLogPostToolCallPlugin` | Records tool call results in the AI interaction audit log. | | `Spryker\\Zed\\AiFoundation\\Communication\\Plugin` |\n| `NavigationToolSetPlugin` | Registers tools for resolving Back Office navigation paths. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation` |\n| `OrderManagementToolSetPlugin` | Registers tools for fetching order lists and OMS process information. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation` |\n| `OrderDetailsToolSetPlugin` | Registers tools for fetching detailed order data by reference or ID. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation` |\n| `DiscountManagementToolSetPlugin` | Registers tools for reading, creating, and updating discounts. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation` |\n\n**src\/Pyz\/Zed\/AiFoundation\/AiFoundationDependencyProvider.php**\n\n```php\n<?php\n\nnamespace Pyz\\Zed\\AiFoundation;\n\nuse Spryker\\Zed\\AiFoundation\\AiFoundationDependencyProvider as SprykerAiFoundationDependencyProvider;\nuse Spryker\\Zed\\AiFoundation\\Communication\\Plugin\\AuditLogPostPromptPlugin;\nuse Spryker\\Zed\\AiFoundation\\Communication\\Plugin\\AuditLogPostToolCallPlugin;\nuse Spryker\\Zed\\AiFoundation\\Communication\\Plugin\\Log\\AiInteractionHandlerPlugin;\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation\\BackofficeAssistantSsePostToolCallPlugin;\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation\\BackofficeAssistantSsePreToolCallPlugin;\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation\\DiscountManagementToolSetPlugin;\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation\\NavigationToolSetPlugin;\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation\\OrderDetailsToolSetPlugin;\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\AiFoundation\\OrderManagementToolSetPlugin;\n\nclass AiFoundationDependencyProvider extends SprykerAiFoundationDependencyProvider\n{\n    \/**\n     * @return array<\\Spryker\\Zed\\AiFoundation\\Dependency\\Plugin\\PostPromptPluginInterface>\n     *\/\n    protected function getPostPromptPlugins(): array\n    {\n        return [\n            new AuditLogPostPromptPlugin(),\n        ];\n    }\n\n    \/**\n     * @return array<\\Spryker\\Zed\\AiFoundation\\Dependency\\Plugin\\PreToolCallPluginInterface>\n     *\/\n    protected function getPreToolCallPlugins(): array\n    {\n        return [\n            new BackofficeAssistantSsePreToolCallPlugin(),\n        ];\n    }\n\n    \/**\n     * @return array<\\Spryker\\Zed\\AiFoundation\\Dependency\\Plugin\\PostToolCallPluginInterface>\n     *\/\n    protected function getPostToolCallPlugins(): array\n    {\n        return [\n            new BackofficeAssistantSsePostToolCallPlugin(),\n            new AuditLogPostToolCallPlugin(),\n        ];\n    }\n\n    \/**\n     * @return array<\\Spryker\\Shared\\Log\\Dependency\\Plugin\\LogHandlerPluginInterface>\n     *\/\n    protected function getAiInteractionLogHandlerPlugins(): array\n    {\n        return [\n            new AiInteractionHandlerPlugin(),\n        ];\n    }\n\n    \/**\n     * @return array<\\Spryker\\Zed\\AiFoundation\\Dependency\\Tools\\ToolSetPluginInterface>\n     *\/\n    protected function getAiToolSetPlugins(): array\n    {\n        return [\n            new NavigationToolSetPlugin(),\n            new OrderManagementToolSetPlugin(),\n            new OrderDetailsToolSetPlugin(),\n            new DiscountManagementToolSetPlugin(),\n        ];\n    }\n}\n```\n\nRegister the Twig plugin to inject the chat widget into the Back Office layout:\n\n| PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |\n|--------|---------------|---------------|-----------|\n| `AiCommerceTwigPlugin` | Registers Twig functions and variables required by the Back Office Assistant chat widget. | | `SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\Twig` |\n\n**src\/Pyz\/Zed\/Twig\/TwigDependencyProvider.php**\n\n```php\n<?php\n\nnamespace Pyz\\Zed\\Twig;\n\nuse SprykerFeature\\Zed\\AiCommerce\\Communication\\Plugin\\Twig\\AiCommerceTwigPlugin;\nuse Spryker\\Zed\\Twig\\TwigDependencyProvider as SprykerTwigDependencyProvider;\n\nclass TwigDependencyProvider extends SprykerTwigDependencyProvider\n{\n    \/**\n     * @return array<\\Spryker\\Shared\\TwigExtension\\Dependency\\Plugin\\TwigPluginInterface>\n     *\/\n    protected function getTwigPlugins(): array\n    {\n        return [\n            \/\/ ... other plugins\n            new AiCommerceTwigPlugin(),\n        ];\n    }\n}\n```\n\n{% info_block warningBox \"Verification\" %}\n\nIn the Back Office, make sure the chat widget icon is visible in the Back Office layout after enabling the feature.\n\n{% endinfo_block %}\n\n### 5) Sync configuration\n\nSync the Back Office Assistant configuration to the database:\n\n```bash\nconsole configuration:sync\n```\n\n### 6) Enable the feature\n\nEnable the feature in the Back Office:\n\n1. In the Back Office, go to **AI Commerce&nbsp;<span aria-label=\"and then\">><\/span>&nbsp;Back Office Assistant&nbsp;<span aria-label=\"and then\">><\/span>&nbsp;General**.\n2. Enable **Enable Back Office Assistant**.\n3. Click **Save**.\n\n![Back Office Assistant configuration](https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-commerce\/backoffice-assistant-config.png)\n\n{% info_block warningBox \"Verification\" %}\n\nIn the Back Office, make sure the Back Office Assistant chat icon is visible in the bottom-right corner of any Back Office page.\n\n![Back Office Assistant icon](https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-commerce\/backoffice-assistant-icon.png)\n\n{% endinfo_block %}\n\n## Integrate the feature frontend\n\n### 1) Add the chat widget to the Back Office layout\n\n{% info_block infoBox \"Info\" %}\n\nDo this step only if you have overridden `layout.twig` in the `Gui` module at the project level. If you have not overridden this template, skip to [2) Install frontend dependencies](#2-install-frontend-dependencies).\n\n{% endinfo_block %}\n\nIn `src\/Pyz\/Zed\/Gui\/Presentation\/Layout\/layout.twig`, include the chat widget partial inside the `footer_js` block:\n\n```twig\n{% raw %}\n{% extends '@Spryker:Gui\/Layout\/layout.twig' %}\n\n{% block footer_js %}\n    {% include '@AiCommerce\/Partials\/chat-widget.twig' %}\n    {{ parent() }}\n{% endblock %}\n{% endraw %}\n```\n\n```bash\nconsole cache:empty-all\nconsole twig:cache:warmer\nconsole router:cache:warm-up:backoffice\n```\n\n### 2) Install frontend dependencies\n\nThe chat widget requires the `marked` and `dompurify` npm packages for rendering and sanitizing Markdown responses.\n\nInstall the required npm packages:\n\n```bash\nnpm install marked@^15.0.0 dompurify@^3.2.0\n```\n\n### 3) Apply the frontend changes\n\n```bash\ndocker\/sdk cli console frontend:project:install-dependencies\ndocker\/sdk cli console frontend:zed:build\n```\n\n{% info_block warningBox \"Verification\" %}\n\nIn the Back Office, open the Back Office Assistant chat widget and send a message. Make sure the response is rendered correctly and the widget is functional.\n\n![Back Office Assistant chat](https:\/\/spryker.s3.eu-central-1.amazonaws.com\/docs\/dg\/dev\/ai-commerce\/backoffice-assistant-chat.png)\n\n{% endinfo_block %}\n","pubDate":"Wed, 01 Apr 2026 14:58:55 +0000","link":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/ai\/ai-commerce\/backoffice-assistant\/install-backoffice-assistant.html","guid":"https:\/\/docs.spryker.com\/docs\/dg\/dev\/ai\/ai-commerce\/backoffice-assistant\/install-backoffice-assistant.html"}]}}