<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Spryker Documentation</title>
        <description>Spryker documentation center.</description>
        <link>https://docs.spryker.com/</link>
        <atom:link href="https://docs.spryker.com/feed.xml" rel="self" type="application/rss+xml"/>
        <lastBuildDate>Thu, 10 Sep 2026 10:34:50 +0000</lastBuildDate>
        <generator>Jekyll v4.2.2</generator>
        
        
        <item>
            <title>Restricted products behavior</title>
            <description>&lt;div class=&quot;width-100&quot;&gt;

On this page, you can find commonly encountered cases of product restrictions behavior.
&lt;table cellspacing=&quot;0&quot;&gt;
   &lt;thead&gt;
      &lt;tr&gt;
         &lt;th&gt;Name&lt;/th&gt;
         &lt;th&gt;Blacklist/Whitelist&lt;/th&gt;
         &lt;th&gt;Description&lt;/th&gt;
         &lt;th&gt;Example&lt;/th&gt;
      &lt;/tr&gt;
   &lt;/thead&gt;
   &lt;tbody&gt;
      &lt;tr&gt;
         &lt;td rowspan=&quot;6&quot;&gt;Product Catalog&lt;/td&gt;
         &lt;td rowspan=&quot;2&quot;&gt;Blacklist&lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;If the merchant relation has a blacklist, all buyers in the associated business units cannot interact with any products from the blacklist. The blacklisted products are excluded from view, search, existing lists and carts. If the category is a part of a blacklist, it&apos;s greyed out in the shop navigation, however, you can change this setting on the project level so, for example, that the category is not greyed out.&lt;/p&gt;
            &lt;p&gt;All products assigned to a category are also included in the black/white list.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/categories-blacklist.png&quot; alt=&quot;&quot; /&gt;
            &lt;p&gt;In case the products are added to the category after it was included in a list, it&apos;s reflected after some time with the help of &lt;a href=&quot;/docs/dg/dev/backend-development/data-manipulation/data-publishing/publish-and-synchronization.html&quot;&gt;publish &amp;amp; sync&lt;/a&gt; process.&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;Upon entering the direct link for the blacklisted product, the shop visitor will see &lt;em&gt;404 Not found&lt;/em&gt; page.&lt;/td&gt;
         &lt;td&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/404-not-found-blacklisted-product.png&quot; alt=&quot;&quot; /&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;Whitelist&lt;/td&gt;
         &lt;td&gt;If the merchant relation has a whitelist, all buyers in the associated business units can interact only with the whitelisted products, except if they are also blacklisted. If a category is not part of any whitelist (if a whitelist exists), they are greyed out in navigation (you can also change this setting on the project level so, for example, that category is not greyed out).&lt;/td&gt;
         &lt;td&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/categories-whitelist.png&quot; alt=&quot;&quot; /&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;Blacklist and Whitelist&lt;/td&gt;
         &lt;td&gt;If a product is in a whitelist as well as in a blacklist, Blacklist wins.&lt;/td&gt;
         &lt;td&gt;N/A&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;Neither blacklist nor whitelist&lt;/td&gt;
         &lt;td&gt;If a merchant relation has neither black nor whitelist, all associated business units will not have any product restrictions.&lt;/td&gt;
         &lt;td&gt;N/A&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;Multiple categories&lt;/td&gt;
         &lt;td&gt;In case a product is a part of multiple categories and one category is a part of a list, the product is also a part of that list.&lt;/td&gt;
         &lt;td&gt;N/A&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;Shopping cart&lt;/td&gt;
         &lt;td&gt;Blacklist&lt;/td&gt;
         &lt;td&gt;In case the products that already exist in carts get blacklisted, they are automatically removed from the cart.&lt;/td&gt;
         &lt;td&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/blacklisted-product-in-cart.png&quot; alt=&quot;&quot; /&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Reorder&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;During the &lt;a href=&quot;/docs/pbc/all/customer-relationship-management/latest/base-shop/reorder-feature-overview.html&quot;&gt;reorder&lt;/a&gt; process, products that are restricted but exist in a previous order are automatically removed from the cart.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/reorder-blacklist.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
            &lt;p&gt;In the Order History, the customer is still able to see the order details even if the previously ordered items are currently blacklisted.&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Shopping List&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;If the product, that is added to the shopping list, has been blacklisted, it&apos;s displayed as if it&apos;s unavailable.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/blacklisted-product-in-shopping-list.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Alternative products&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;If a product that has been added to a list of the alternative products, is restricted, it&apos;s not suggested on product pages.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/alternative-product-blacklisted.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Product Groups&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;If any of the products that are added to a product group, is restricted, it&apos;s not displayed in the Shop Application.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/product-groups-blacklisted.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Related Products&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;If any of the related products is added to a blacklist - it&apos;s not displayed in the Shop Application.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/related-product-blacklist.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td rowspan=&quot;2&quot;&gt;
            &lt;p&gt;Product Sets&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Whitelist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;In case any of the products in the product set are added to a whitelist - the other products are not displayed in the shop application.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/product-set-whitelist.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;In the case with the blacklist, when the whole product set is blacklisted - &lt;em&gt;This product is not available&lt;/em&gt; message is shown on the product detail page, though the product set is still displayed on the &lt;em&gt;Product Sets&lt;/em&gt; page.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/product-set-blacklisted.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;CMS&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;If the products from CMS block have been added to a blacklist - they are not displayed on the website.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/cms-blacklisted.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Promotional Products&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;If any of the promotional products are restricted, they are not available for purchase.&lt;/p&gt;
            &lt;p&gt;If all the variants for a promotional product are restricted - the restricted product is not shown at all.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;&lt;img title=&quot;Click Me!&quot; src=&quot;https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/Feature+Walkthroughs/Merchant+Product+Restrictions+Feature+Walkthrough/Restricted+Products+Behavior/promotional-products-blacklist.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Product Bundles&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;If you want to restrict the whole product bundle, a bundle SKU needs to be entered in the blacklist rule. If any of the products contained in a product bundle are restricted, the whole bundle is still available for purchase.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Business on Behalf&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist/Whitelist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;When switching Company User accounts by using the Business on Behalf feature a company user has the product restrictions lists that are assigned to the new company user they are logged in into.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;N/A&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
         &lt;td&gt;
            &lt;p&gt;Product search widget&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;Blacklist&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;If there are products that are blacklisted, they do not appear in search results in the search widget.&lt;/p&gt;
         &lt;/td&gt;
         &lt;td&gt;
            &lt;p&gt;[An image showing a restricted product in the Admin Interface and searching for this product in Yves]&lt;/p&gt;
         &lt;/td&gt;
      &lt;/tr&gt;
   &lt;/tbody&gt;
&lt;/table&gt;

&lt;/div&gt;

{% info_block infoBox &quot;Info&quot; %}

If there are cases you would like to get overview of within Product Restrictions feature, email us.

{% endinfo_block %}
</description>
            <pubDate>Thu, 10 Sep 2026 09:22:51 +0000</pubDate>
            <link>https://docs.spryker.com/docs/pbc/all/merchant-management/latest/base-shop/merchant-product-restrictions-feature-overview/restricted-products-behavior.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/pbc/all/merchant-management/latest/base-shop/merchant-product-restrictions-feature-overview/restricted-products-behavior.html</guid>
            
            
        </item>
        
        <item>
            <title>Migrate from OpenSearch 1.3 to 3.5</title>
            <description>This document describes how to migrate an OpenSearch cluster used by a Spryker project from version 1.3 to 3.5.

Between major OpenSearch versions, an index or a cluster setting can become incompatible with the target version, for example because of an outdated Lucene index format, a deprecated setting, or a breaking plugin change. OpenSearch does not support skipping major versions and cannot be upgraded in place while such incompatibilities exist, so the upgrade is blocked until you resolve them. To resolve this, you upgrade the cluster incrementally, from 1.3 to 2.19, and then from 2.19 to 3.5, fixing every incompatibility before each upgrade.

{% info_block warningBox &quot;Verification&quot; %}

Before you start, test the migration in a non-production environment. Blocking writes to an index makes it read-only until the reindexing is complete, so plan the migration for a maintenance window.

{% endinfo_block %}

## 1. Update the required modules

You only need to update the packages for the features used in your project. Check the following table and update the packages that are installed in your project to at least the specified versions:

| Package | Minimum version |
| --- | --- |
| `spryker/sales-return-search` | 1.4.1 |
| `spryker/merchant-search` | 1.3.1 |
| `spryker/product-review` | 2.15.1 |
| `spryker/search-elasticsearch` | 1.23.1 |
| `spryker/service-point-search` | 1.4.1 |
| `spryker-feature/self-service-portal` | 20.9.1 |

Update the packages installed in your project using Composer:

```bash
composer update spryker/merchant-search:&quot;^1.3.1&quot; spryker/product-review:&quot;^2.15.1&quot; spryker/sales-return-search:&quot;^1.4.1&quot; spryker/search-elasticsearch:&quot;^1.23.1&quot; spryker/service-point-search:&quot;^1.4.1&quot; spryker-feature/self-service-portal:&quot;^20.9.1&quot;
```

If your project overrides the search schema of these modules, apply the equivalent changes to your project-level search schema as well.

## 2. Check the upgrade eligibility

Consult the breaking changes and deprecation notices for OpenSearch 2.19, and check your indexes and cluster settings against them to determine whether the cluster is eligible for the upgrade.

- If the cluster is eligible, upgrade it to 2.19 and continue to [Check the upgrade eligibility for 3.5](#check-the-upgrade-eligibility-for-35).
- If the cluster is not eligible, one or more incompatibilities block the upgrade.
  - For an index with an incompatible index format, unblock the upgrade by reindexing it as described in the following section.
  - For any other incompatibility, for example a deprecated index setting or a breaking plugin change, fix it first. Only continue with the upgrade after all the incompatibilities are resolved.

## 3. Reindex an index to unblock the upgrade

Repeat the following steps for every index with an incompatible index format. Replace `&lt;index&gt;` with the name of the index you are migrating.

### 3.1. Block writes to the index

To prevent data from changing while the index is being cloned, block write operations:

```json
PUT /&lt;index&gt;/_settings
{
  &quot;settings&quot;: {
    &quot;index.blocks.write&quot;: true
  }
}
```

### 3.2. Clone the index

Clone the index into a temporary index:

```json
PUT /&lt;index&gt;/_clone/&lt;index&gt;_tmp
```

### 3.3. Verify the document count

Compare the document count of `&lt;index&gt;` and `&lt;index&gt;_tmp`. The counts must match before you continue.

### 3.4. Delete the original index

```json
DELETE /&lt;index&gt;
```

### 3.5. Re-create the index and its schema

Re-create the index and install its schema using the following console command:

```bash
console search:setup:sources
```

### 3.6. Reindex the documents

Reindex the documents from the temporary index back into the newly created `&lt;index&gt;`:

```json
POST /_reindex?slices=2&amp;wait_for_completion=false
{
  &quot;source&quot;: {
    &quot;index&quot;: &quot;&lt;index&gt;_tmp&quot;
  },
  &quot;dest&quot;: {
    &quot;index&quot;: &quot;&lt;index&gt;&quot;
  }
}
```

### 3.7. Verify the document count again

Compare the document count of `&lt;index&gt;` and `&lt;index&gt;_tmp` again. The counts must match before you continue.

### 3.8. Delete the temporary index

```json
DELETE /&lt;index&gt;_tmp
```

After you reindex all the blocking indexes, upgrade the cluster to version 2.19.

## 4. Check the upgrade eligibility for 3.5

Consult the breaking changes and deprecation notices for OpenSearch 3.5, and check your indexes and cluster settings on version 2.19 against them to determine whether the cluster is eligible for the upgrade.

- If the cluster is eligible, upgrade it to 3.5.
- If the cluster is not eligible, incompatibilities again block the upgrade. Resolve them the same way as in step 2: reindex every index with an incompatible index format by repeating the steps in [3. Reindex an index to unblock the upgrade](#3-reindex-an-index-to-unblock-the-upgrade), and fix any other incompatibility. Then upgrade the cluster to 3.5.
</description>
            <pubDate>Thu, 10 Sep 2026 09:15:04 +0000</pubDate>
            <link>https://docs.spryker.com/docs/pbc/all/search/latest/base-shop/install-and-upgrade/migrate-from-opensearch-1.3-to-3.5.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/pbc/all/search/latest/base-shop/install-and-upgrade/migrate-from-opensearch-1.3-to-3.5.html</guid>
            
            
        </item>
        
        <item>
            <title>Using the Support Hub</title>
            <description>This document describes how to use the Support Hub to create and manage your tickets.

## Prerequisites

- Log in at the [Spryker Portal](https://portal.spryker.com). If you do not have access to the Spryker Portal, request it using [this form](https://portal.spryker.com/request-access).
- Go to the Support Hub using the squares menu in the top right.

## Create a new ticket

To create a new ticket, click **Create a ticket** and follow the wizard.

When 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).


The following are the top-level categories of tickets and their descriptions.

### Report a Problem or Incident

Problems can be reports of a suspected 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.

### Ask a Question

Use this category for any questions about Spryker. We want knowledge about Spryker to be available to everyone, so we will provide you with a
link to the [Spryker community Slack]({{ site.community_slack_invite }}) to ask your question there. If there are docs on the topic, we will provide a link to that.

### Infrastructure Change Request and Access Management

Request all currently supported standard changes, such as requesting changes to non-production environment sizing, IAM users and environment provisioning.

### Reporting a Problem with Spryker CI

Report an issue with Spryker CI (Buddy), such as errors or issues with its UI or pipeline runs.

### Announce a Go Live

Inform the Customer Success Team that you are close to going live.

### Request Professional Services

This category offers a selection of professional services. For example, you may need it when implementing a complex custom feature.

### Request Help with Spryker Code Upgrader

Request help with the Upgrader. These requests are processed by our Upgrader experts.

### Announce High Traffic/Load

Let us know about events or time periods in which you expect a higher than usual load on your production environments.
We can use this information to check the auto-scaling settings and evaluate if they need to be adjusted to meet your demands.

### Emergencies

Emergencies 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).
Do not use this category to speed up requests or problem reports. Emergencies need to be associated with significant risk or business impact, like revenue, security, or go-lives.

### Info on Change Requests

{% info_block warningBox &quot;Plan your change requests and use the right request form&quot; %}

Because of verification processes and role-based access control mechanisms, change requests take some time to process. Expect 3-5 days of processing time.

Because of contractual reasons, only customers can request new environments or access to environment monitoring, not partners.

{% endinfo_block %}

## Manage tickets

Click **View tickets** to open the list of tickets your organization has opened. To view the details of a particular ticket, click **Details**.
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.

### Ticket receipts and notifications

When 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.

If 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 labeling rules in your email client:


- Ticket confirmation emails are sent when you create a ticket or when its status is updated. Subject pattern:

```bash
Case Receipt - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME} - Status: {STATUS}. {TRACKING ID}
```

- Change request confirmation emails are sent when you create a change request. Subject pattern:

```bash
Change Request Receipt - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME} - Status: {STATUS}. {TRACKING ID}
```

- ETA update notification emails are sent when the ETA on your ticket is updated. Subject pattern:

```bash
Case ETA Update - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME} - ETA: {ETA}. {TRACKING ID}
```

- Emergency ticket emails are sent when you declare an emergency or your emergency ticket&apos;s status is updated. Subject pattern:

```bash
Emergency {STATUS} - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME} {TRACKING ID}
```

- Ticket comment notification emails are sent when there is a new comment in your ticket. Subject pattern:

```bash
Case Comment Notification - Case ID: {CASE NUMBER} - Customer: {CUSTOMER NAME} - Status: {STATUS} {TRACKING ID}
```
</description>
            <pubDate>Thu, 10 Sep 2026 08:29:18 +0000</pubDate>
            <link>https://docs.spryker.com/docs/about/all/support/using-the-support-hub.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/about/all/support/using-the-support-hub.html</guid>
            
            
        </item>
        
        <item>
            <title>Understanding SLAs</title>
            <description>Like any legal text, Service Level Agreements (SLAs) can be hard to understand for the uninitiated. We strive to keep our SLAs clear and comprehensive, but sometimes it&apos;s better to explain some core concepts more verbose.

## What we expect from you

Fulfilling SLA is a two-way street, and we cannot achieve good results without you. The following is what we expect from our customers.

### Keeping Spryker environments up-to-date

We generally expect our customers to keep their Spryker environment up to date. The reason for this is having multiple layers.
We release updates to introduce new features, performance improvements, and security enhancements. Especially the last ones you do not want to miss. We want our customers to have fast, responsive, and more secure shops.
Up-to-date code generally means more stability, better support, and compatibility for third-party applications. If you use the latest versions, it means that you are using the best and most up-to-date version of the code we have to offer. Looking at the motivations to keep up-to-.date listed above, this is not only good for you, but it&apos;s good for us too. Working with a project that has recent code means that we have an easier time understanding what is going on. This reduces case resolution time and makes communication between you, Spryker Support, and Development much easier.

### Keep it in English

At Spryker people from around the world work together to provide outstanding products and services. To facilitate communication flow and reduce barriers, we decided to make English our business language. When getting in contact with Spryker Support, we ask you to do the same.

### Report problems in a timely manner

If you discover a problem with Spryker Software,  let us know immediately. Avoid ignoring a problem that you find, or work around it without reporting it to us. Not only would this prevent us from making our software better, but your workaround might not be maintainable and could cause you problems with upgradability or reduce your flexibility sometime in the future.

### Bring the right information

Ensure that every case you open with us includes the information we need to work on it. To learn what info matters most, see [Getting the most out of Spryker Support](/docs/about/all/support/getting-the-most-out-of-spryker-support.html).

### Assess business impact realistically

To make sure that we resolve the right cases first, we need to triage and prioritize. You can help us to do this better if you assess and specify the business impact of your problem appropriately. For a more detailed explanation of what business impact is and how priorities work have a look into this [article](/docs/about/all/support/support-ticket-statuses.html#prioritizing-bug-tickets).

## What you can expect from us

In our SLAs, we guarantee certain [First Response Times](/docs/about/all/support/how-spryker-support-works.html#first-response-time).
You can expect us to react to your cases within the time that is specified in your SLA. While we work to resolve high-priority issues as fast as possible, we do not and cannot guarantee resolution times for the issues you open with us because of the breadth of cases we offer to work on. Guaranteeing resolution times would make it necessary for us to make the definition of the cases we accept stricter, which ultimately will makes it harder and more bureaucratic for you to work with us.

### Infrastructure support

For Spryker customers using our PaaS, we can also support infrastructure-related issues, like fault correction and recovery. Because of the critical nature of infrastructure issues, we generally offer a faster response time on these issues and have built robust processes that ensure that these matters are resolved timely and that we proactively update the customer along the way.

### Software support

All Spryker customers can benefit from the support we offer for our Spryker software. We want the software we develop to be easy to work with and reliable. If defects happen that are reproducible for us in the out-of-the-box (OOTB) Spryker installation, we generally file a bug report and communicate the Jira ticket number, so you can reference it in a later communication. Since software development is a process with many steps, sometimes we provide project-level fixes for you rather than wait for the fix to be implemented in our core product and then ship it to you by an update. We make sure, though, that our other customers can benefit from the improvement your bug report introduced to our product in a timely manner.

## What else you can do to prevent issues

There is a number of things you can do to avoid problems.

### Keep updated on Spryker

Keeping your Spryker environment up to date is important, but it&apos;s equally important to keep your knowledge about what is going on with Spryker updated, too.
The [Spryker community Slack]({{ site.community_slack_invite }}) is where people using Spryker come to discuss it, and we invite every customer to join and contribute actively. Often, you will hear the latest news first there, including announcements of the monthly Spryker User Group Meetups in which internal Spryker teams and community members share and discuss the latest developments.

Also, subscribe to our new newsletter (soon to come) and be sure to check out our Technical News Page (soon to come), for the latest important news.

### Enroll in the Spryker Safari

This is a general recommendation that not only can teach you and your team how to build great shops with Spryker Code, but we offer several courses for all kinds of Spryker stakeholders. Currently, we offer developer courses, business courses, and sales courses with other interesting courses currently being developed.

### Learn more about how we work

We are working on being more transparent about how we work internally because we believe it makes working with us easier. To learn about our processes, take a look at the other articles in the Support section of our documentation
</description>
            <pubDate>Thu, 10 Sep 2026 08:29:18 +0000</pubDate>
            <link>https://docs.spryker.com/docs/about/all/support/understanding-slas.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/about/all/support/understanding-slas.html</guid>
            
            
        </item>
        
        <item>
            <title>Support case escalations</title>
            <description>An escalation is a situation that usually involves a partner or customer having an urgent or especially important problem that cannot immediately be solved to the satisfaction of everyone involved, and the problem is escalated to senior leadership or other departments in an effort to resolve the problem.

## Example of a situation leading up to an escalation

Customer A discovers a problem with Spryker that has a significant impact on their plans to launch a new feature next week. They open a support case with Spryker. The support representative dealing with the case informs the customer that they have verified the bug, and a report has been filed with development to fix the bug. The mention that the bug is most likely to be fixed within 3-4 weeks, which conflicts with the customer&apos;s feature release.

While Support always tries to accommodate the plans of customers and partners, this might not always be possible. Naturally, this leads to frustration, and company A might feel the need to reach out to their account manager, partner manager, customer success manager, or even a member of Spryker leadership to force or at least expedite problem resolution that way.

While this strategy might feel like the right thing to do (we need to do something right?), it produces suboptimal results and consumes resources, nerves, and time. It also puts a strain on the relationship with the customer or partner and often introduces a lot of emotions that can stand in the way of orderly resolution.

## Handling escalations

In Support, we acknowledge that we cannot always produce a satisfying result. We do not always get it right, and sometimes our hands might simply be tied. Escalations happen, and it&apos;s important for us to steer them into a constructive and orderly direction right away that ensures:
1. It is easy for a customer or partner to escalate an issue.
2. The customer&apos;s or partner&apos;s problem is evaluated by the right audience.
3. The stakeholders align quickly to find a feasible strategy going forward.

### Initiate an escalation

Creating an [Emergency Case](/docs/about/all/support/using-the-support-hub.html#emergencies) always starts an escalation. You will receive an email notifying you that an escalation has been started.

### The escalation process

The escalation process is designed in a way to create visibility for the right audience and is built in a robust way to ensure quality standards. Facing a problem with significant business impact is stressful and we tried to build a streamlined process that is easy to follow for partners and customers and easy to operate for our support reps. An escalation has seven statuses. The customer and partner receive email notifications when the status changes.

`STARTED`. A customer or partner has created an emergency case. Internal stakeholders are informed and began evaluating the information provided. In cases where the Emergency Case option is misused, the Escalation is canceled, and the requester is informed about it.

`ACKNOWLEDGED`. If the escalation is valid, it&apos;s acknowledged by the support rep that takes care of the case. They do not inform internal stakeholders and see to it that a solution is developed. They also make sure to update the customer and partner at regular intervals on their progress.

`SOLUTION PROPOSED`. Once the team has found a solution that either fixes the problem outright, or at least mitigates its impact, they propose a solution, and the partner and customer are asked to accept or reject the proposed solution.

`CLOSED`. After an acceptable solution is found, the escalation (not the case) is closed. This means that the urgency of the matter was successfully reduced, and the case can be handled within the normal support process again. Usually, the internal stakeholders involved are debriefed at this point.

After a valid escalation is over, Post Mortem is held and the results are shared with the partner and customer. The point of this is to make it less likely that a similar situation that causes an escalation likely can occur in the future. If the escalation was caused by infrastructure problems in production systems, a technical Root Cause Analysis (RCA) will also be shared.

### What we ask from you during an escalation

This is the most effective way to bring your issue to the attention of a broad audience. We ask you to not misuse this option to expedite regular bug resolution or case processing. It makes several people in Spryker very busy and might therefore even have the opposite effect.

When you start an escalation, refrain from contacting other Spryker personnel about the same issue on different channels. This introduces confusion and information asymmetry which reduces the effectiveness of this process significantly.

After an escalation is acknowledged, support reps might determine that real-time communication is necessary to speed up the resolution process. After creating an emergency case, make sure you are available for immediate correspondence.

Work with us. We can get to the bottom of what and how things went wrong after we mitigated the problem. Let&apos;s work together in a constructive, objective manner.
</description>
            <pubDate>Thu, 10 Sep 2026 08:29:18 +0000</pubDate>
            <link>https://docs.spryker.com/docs/about/all/support/support-case-escalations.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/about/all/support/support-case-escalations.html</guid>
            
            
        </item>
        
        <item>
            <title>Quickstart guide: Install Spryker on Windows</title>
            <description>This document describes how to quickly install Spryker on Windows in Development mode. If you are installing Spryker for the first time or need detailed instructions, we recommend starting with [Install Spryker](/docs/dg/dev/set-up-spryker-locally/install-spryker/install-spryker.html).

To install Spryker on Windows, follow these steps:

## Prerequisites

Install the following applications:

- [Ubuntu](https://apps.microsoft.com/detail/9pdxgncfsczv)
- [Docker](https://www.docker.com/)


## 1. Clone the Demo Shop

{% info_block warningBox %}

Product images, product data, other images or fonts displayed in a demo shop are examples, and you may need to purchase your own licenses to use any of them.

{% endinfo_block %}

```shell
git clone https://github.com/spryker-shop/b2b-demo-marketplace -b {{page.release_tag}} --single-branch ./b2b-demo-marketplace &amp;&amp; \
cd b2b-demo-marketplace &amp;&amp; \
git clone https://github.com/spryker/docker-sdk --single-branch docker &amp;&amp; \
docker/sdk bootstrap deploy.dev.yml
```

## 2. Update the hosts

Update `C:\Windows\System32\drivers\etc\hosts` using the instructions provided in the output of the previous step. The instructions should be similar to the following:

![update-hosts](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/setup/quickstart-guides-install-spryker/quickstart-guide-install-spryker-on-macos-and-linux/update-hosts.png)

## 3. Build and start the instance

```shell
docker/sdk up
```

The project is now running. For the full list of the project&apos;s endpoints, see `http://spryker.local`.
</description>
            <pubDate>Thu, 10 Sep 2026 08:29:18 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/set-up-spryker-locally/quickstart-guides-install-spryker/quickstart-guide-install-spryker-on-windows.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/set-up-spryker-locally/quickstart-guides-install-spryker/quickstart-guide-install-spryker-on-windows.html</guid>
            
            
        </item>
        
        <item>
            <title>Quickstart guide: Install Spryker on macOS and Linux</title>
            <description>This document describes how to quickly install Spryker on macOS or Linux in Development mode. If you are installing Spryker for the first time or need detailed instructions, we recommend starting with [Install Spryker](/docs/dg/dev/set-up-spryker-locally/install-spryker/install-spryker.html).

To install Spryker on macOS or Linux, follow these steps:

## Prerequisites

- Install [Docker](https://www.docker.com/) or [OrbStack](https://orbstack.dev/) (macOS only).

- macOS: Install or update Mutagen and Mutagen Compose. Stop and resolve issues, if any of the commands fail.

```bash
brew list | grep mutagen | xargs brew remove
brew install mutagen-io/mutagen/mutagen mutagen-io/mutagen/mutagen-compose
mutagen daemon stop
mutagen daemon start
```


## 1. Clone the Demo Shop

{% info_block warningBox %}

Product images, product data, other images or fonts displayed in a demo shop are examples, and you may need to purchase your own licenses to use any of them.

{% endinfo_block %}

```shell
git clone https://github.com/spryker-shop/b2b-demo-marketplace -b {{page.release_tag}} --single-branch ./b2b-demo-marketplace &amp;&amp; \
cd b2b-demo-marketplace &amp;&amp; \
git clone https://github.com/spryker/docker-sdk --single-branch docker &amp;&amp; \
docker/sdk bootstrap deploy.dev.yml
```

## 2. Update the hosts

Update the hosts file using the command provided in the output of the previous step. It should be similar to the following:

![update-hosts](https://spryker.s3.eu-central-1.amazonaws.com/docs/scos/dev/setup/quickstart-guides-install-spryker/quickstart-guide-install-spryker-on-macos-and-linux/update-hosts.png)

## 3. Build and start the instance

```shell
docker/sdk up
```

The project is now running. For the full list of the project&apos;s endpoints, see `http://spryker.local`.
</description>
            <pubDate>Thu, 10 Sep 2026 08:29:18 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/set-up-spryker-locally/quickstart-guides-install-spryker/quickstart-guide-install-spryker-on-macos-and-linux.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/set-up-spryker-locally/quickstart-guides-install-spryker/quickstart-guide-install-spryker-on-macos-and-linux.html</guid>
            
            
        </item>
        
        <item>
            <title>Publish and Synchronization</title>
            <description>To serve data quickly, your shop application reads from Redis (key–value storage) and Elasticsearch (search and analytics). The client does not access the primary SQL database directly. Instead, Spryker uses the Publish and Synchronize (P&amp;S) mechanism to move data from the relational database to Redis and Elasticsearch.

P&amp;S denormalizes and distributes data to achieve the following:

- Reduce the load on the master database.

- Deliver localized data, such as pricing, availability, and product details, in a format prepared for the Storefront.

- Run queries, which improves Storefront performance.

Benefits of P&amp;S:

- Near real-time updates because empty queues are checked every second by default.

- Batched SQL queries during publishing for better performance.

- Incremental exports; full re-exports are not needed.

- Safe fallback: the SQL database always holds the source of truth. You can re-sync at any time.  

- Store- and locale-specific data support.

- Spryker relies on Propel behaviors to fire events automatically whenever you save, update, or delete an entity. So you do not need to call any P&amp;S code manually.

## P&amp;S process

P&amp;S process schema:

![ps-process-overview](https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/backend-development/data-manipulation/data-publishing/publish-and-synchronization.md/ps-process-overview.png)


{% raw %}
─────────▶ (solid): Synchronous call or direct write
- - - - -▶ (dashed): Asynchronous event, queue, or deferred processing
{% endraw %}

### 1. Publish 

You can start the publish process using automated or manual event triggering.

#### Automated event triggering

When an entity implements Propel Event behavior, every create, update, or delete operation automatically triggers a corresponding publish event. This behavior ensures that entity changes are immediately captured and propagated through the system.

For example, saving an abstract product triggers a `create abstract product` event:

```php
$productAbstractEntity = SpyProductAbstractQuery::create()-&gt;findOne();
$productAbstractEntity-&gt;setColorCode(&quot;#FFFFFF&quot;);
$productAbstractEntity-&gt;save();
```

Calling `save()`, the entity invokes the `saveEventBehaviorEntityChange()` method, which creates a `SpyEventBehaviorEntityChange` record. This record is saved into the database and remains pending until the `onTerminate` Symfony event is triggered. During the `onTerminate` event, all `SpyEventBehaviorEntityChange` entries, produced by the current process, are dispatched into the corresponding message queues.

The event dispatcher plugin responsible for this behavior is `Spryker\Zed\EventBehavior\Communication\Plugin\EventDispatcher\EventBehaviorEventDispatcherPlugin`.

{% info_block infobox %}

If the process finishes early, and events are not processed during runtime, they are handled automatically by the command in Jenkins:

```bash
vendor/bin/console event:trigger:timeout
```

This command is executed every five minutes by default.

{% endinfo_block %}


#### Manual event triggering

You can trigger the publish event manually using the event facade:

```php
$this-&gt;eventFacade-&gt;trigger(CmsStorageConfig::CMS_KEY_PUBLISH_WRITE, (new EventEntityTransfer())-&gt;setId($id));
```

Manual event triggering works best when an entity passes several stages before it becomes available to customers. The typical use case is content management or data import. For example, when you create a page, it usually remains a draft until you decide to publish it, or when you release a new product to the market.

#### Event in the queue

When the publish process is triggered, one or more event messages are posted to queues. Each message includes metadata about the event that triggered it:

- Event name

- The affected entity&apos;s ID

- Names of the corresponding publisher and transfer classes

- A list of modified columns

- Foreign keys used to trace back the updated Propel entities

The message does not include the actual changed data because the data might change before the event is being processed.

Example:

```json
{
	&quot;listenerClassName&quot;:&quot;Spryker\\Zed\\UrlStorage\\Communication\\Plugin\\Event\\Listener\\UrlStorageListener&quot;,
	&quot;transferClassName&quot;:&quot;Generated\\Shared\\Transfer\\EventEntityTransfer&quot;,
	&quot;transferData&quot;:{
		&quot;event&quot;:&quot;Entity.spy_url.update&quot;,
		&quot;name&quot;:&quot;spy_url&quot;,
		&quot;id&quot;:488,
		&quot;foreign_keys&quot;:{
			&quot;spy_url.fk_resource_page&quot;:7,
			&quot;spy_url.fk_resource_product_abstract&quot;:null,
			&quot;spy_url.fk_resource_redirect&quot;:null,
			&quot;spy_url.fk_resource_product_set&quot;:null,
			&quot;spy_url.fk_resource_categorynode&quot;:null,
			&quot;spy_url.fk_locale&quot;:46
		},
	&quot;modified_columns&quot;:[
		&quot;spy_url.url&quot;
	]
	},
	&quot;eventName&quot;:&quot;Entity.spy_url.update&quot;
}
```

### 2. Synchronize

Synchronize is the process of transferring data from the database to a storage, such as Redis and Elasticsearch, making it accessible to fast customer-facing applications.

After a publish event is triggered and a message is placed in a queue (RabbitMQ), the following process takes place:

1. The `vendor/bin/console queue:worker:start` command, typically executed via Jenkins, scans for all non-empty queues.

2. For each non-empty queue, a subprocess is started using the following command:


```bash
vendor/bin/console queue:task:start {queueName}
```

`{queueName}` is the name of the non-empty queue being processed.

3. This command identifies the appropriate listener responsible for processing the messages in this queue.

4. Based on the listener logic, storage or search entities are calculated.

5. These entities are persisted in the database.


## Synchronization types

P&amp;S supports two types of synchronization: asynchronous and direct. Their differences are described in the following sections.

### Asynchronous synchronization

Asynchronous synchronization provides greater stability, although it may take slightly longer to complete. It works as follows:

1. When a storage or search entity is saved to the database, a new message is generated and placed into a dedicated synchronization queue in RabbitMQ.

2. `vendor/bin/console queue:worker:start` command detects this non-empty queue and spawns a child process using the `vendor/bin/console queue:task:start {queueName}` command.

3. During execution, the message is processed, and the resulting data is stored in Redis or Elasticsearch.

Asynchronous sync is used by default when you implement P&amp;S.


### Direct synchronize

Direct synchronize uses in-memory storage to temporarily hold synchronization messages and writes them at the end of the request lifecycle instead of using queues. To improve performance and flexibility, you can enable this method at the project level.

How it works:

1. When a storage or search entity is saved to the database, synchronization messages are stored in the memory of the current PHP process.

2. After the console command completes, Symfony triggers the `onTerminate` event.

3. All messages stored in memory are written directly to Redis and/or Elasticsearch.

![direct-ps-process](https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/backend-development/data-manipulation/data-publishing/publish-and-synchronization.md/direct-ps-process.png)


{% raw %}
─────────▶ (solid): Synchronous call or direct write
- - - - -▶ (dashed): Asynchronous event, queue, or deferred processing
{% endraw %}

For instructions on configuring direct sync, see [Configure direct synchronize](/docs/dg/dev/backend-development/data-manipulation/data-publishing/configurartion/configure-direct-synchronize).

### Key differences from asynchronous synchronization

| Aspect              | Asynchronous Sync                                      | Direct Sync                                                       |
|---------------------|--------------------------------------------------------|-------------------------------------------------------------------|
| Message queue       | Required                                              | Skipped                                                           |
| Processing delay    | Delay is caused by queuing and worker execution.            | Processed after the command ends without a delay.                |
| Performance impact  | Slower during command execution because of additional processing steps. | Faster during command execution.                                  |
| Use case            | Default; scalable for large data volumes.            | Optimized for speed and reduced infrastructure overhead; performs better with low data volumes. |


Asynchronous synchronization is more stable, easier to handle errors, and works with bigger amounts of data.

Direct synchronization provides faster results, and is particularly useful for the following use cases:

- Test environments

- Small projects

- Performance-critical operations where immediate consistency is preferred

## P&amp;S process example

The following walkthrough shows how the P&amp;S mechanism moves product-abstract data from the Spryker backend to Redis and Elasticsearch. The example is based on `SpyProductAbstract` sync in the B2B Marketplace Demo Shop. 

### 1. Publish

When you save a `SpyProductAbstract` entity in the Back Office - such as clicking **Save** on a product page - Spryker immediately triggers the P&amp;S workflow. In this example, the product is enabled in two stores:


![publish-stores](https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/backend-development/data-manipulation/data-publishing/publish-and-synchronization.md/publish-stores.png)

During the save operation, Spryker generates multiple events called messages and places them in RabbitMQ.

### 2. Synchronize

RabbitMQ now contains several events that relate to the product abstract and its dependent entities–for example, product concrete, URL storage, and price.

#### Asynchronous synchronization

##### Storage events


1. Queue: `publish.product_abstract` receives a storage event. 

2. Listener: `ProductAbstractStoragePublishListener` (registered in `ProductStorageEventSubscriber.php`) consumes the event. 
This message contains only metadata. The actual payload is constructed later by the storage or search listeners.


Event example:

```php
{
  &quot;listenerClassName&quot;: &quot;Spryker\\Zed\\ProductStorage\\Communication\\Plugin\\Event\\Listener\\ProductAbstractStoragePublishListener&quot;,
  &quot;transferClassName&quot;: &quot;Generated\\Shared\\Transfer\\EventEntityTransfer&quot;,
  &quot;transferData&quot;: {
    &quot;additional_values&quot;: [],
    &quot;id&quot;: 416,
    &quot;foreign_keys&quot;: {
      &quot;spy_product_abstract.fk_tax_set&quot;: 1
    },
    &quot;modified_columns&quot;: [
      &quot;spy_product_abstract.approval_status&quot;
    ],
    &quot;event&quot;: &quot;Entity.spy_product_abstract.update&quot;,
    &quot;name&quot;: &quot;spy_product_abstract&quot;,
    &quot;original_values&quot;: []
  },
  &quot;eventName&quot;: &quot;Entity.spy_product_abstract.update&quot;
}
```


3. The listener does the following processing: 
   1. Creates a `SpyProductAbstractStorage` entity
   2. Populates the entity with the data that will be used on the frontend
   3. Saves the data to the `spy_product_abstract_storage` table, one row per store and locale 

![async-sync-processing](https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/backend-development/data-manipulation/data-publishing/publish-and-synchronization.md/async-sync-processing.png)


4. Follow-up event: The listener sends a new message to the `sync.storage.product` queue. 


Message example:

```php
{
  &quot;listenerClassName&quot;: &quot;Spryker\\Zed\\ProductStorage\\Communication\\Plugin\\Event\\Listener\\ProductAbstractStoragePublishListener&quot;,
  &quot;transferClassName&quot;: &quot;Generated\\Shared\\Transfer\\EventEntityTransfer&quot;,
  &quot;transferData&quot;: {
    &quot;additional_values&quot;: [],
    &quot;id&quot;: 416,
    &quot;foreign_keys&quot;: {
      &quot;spy_product_abstract.fk_tax_set&quot;: 1
    },
    &quot;modified_columns&quot;: [
      &quot;spy_product_abstract.approval_status&quot;
    ],
    &quot;event&quot;: &quot;Entity.spy_product_abstract.update&quot;,
    &quot;name&quot;: &quot;spy_product_abstract&quot;,
    &quot;original_values&quot;: []
  },
  &quot;eventName&quot;: &quot;Entity.spy_product_abstract.update&quot;
}
```

&lt;/details&gt;

5. Worker: Jenkins launches `vendor/bin/console queue:worker:start`, which invokes `SynchronizationFacade::processStorageMessages()`. 

6. Result: All storage messages are written to Redis. 


##### Search event


1. Queue: `publish.page_product_abstract` receives a search event. 

2. Listener: `ProductPageProductAbstractPublishListener` (registered in `ProductPageSearchEventSubscriber.php`) consumes the message. 


Message example:

```php
{
  &quot;listenerClassName&quot;: &quot;Spryker\\Zed\\ProductStorage\\Communication\\Plugin\\Event\\Listener\\ProductAbstractStoragePublishListener&quot;,
  &quot;transferClassName&quot;: &quot;Generated\\Shared\\Transfer\\EventEntityTransfer&quot;,
  &quot;transferData&quot;: {
    &quot;additional_values&quot;: [],
    &quot;id&quot;: 416,
    &quot;foreign_keys&quot;: {
      &quot;spy_product_abstract.fk_tax_set&quot;: 1
    },
    &quot;modified_columns&quot;: [
      &quot;spy_product_abstract.approval_status&quot;
    ],
    &quot;event&quot;: &quot;Entity.spy_product_abstract.update&quot;,
    &quot;name&quot;: &quot;spy_product_abstract&quot;,
    &quot;original_values&quot;: []
  },
  &quot;eventName&quot;: &quot;Entity.spy_product_abstract.update&quot;
}
```

3. The listener does the following processing: 
    1. Creates a `SpyProductAbstractPageSearch` entity
    2. Populates the entity with data
    3. Saves the entity to the `spy_product_abstract_page_search` table, one row per store and locale 

![search-event-processing](https://spryker.s3.eu-central-1.amazonaws.com/docs/dg/dev/backend-development/data-manipulation/data-publishing/publish-and-synchronization.md/search-event-processing.png)

4. Follow-up event: The listener sends a new message to the `sync.search.product` queue. 

5. Worker: Jenkins launches `vendor/bin/console queue:worker:start`, which invokes `SynchronizationFacade::processSearchMessages()`. 

6. Result: All search messages are indexed in Elasticsearch. 

By following this workflow, Spryker makes all product changes made in the Back Office available in Redis and Elasticsearch with minimal delay, even across multiple stores and locales.

#### Direct synchronization

In direct synchronization mode, the behavior of entities, such as `SpyProductAbstractPageSearch` and `SpyProductAbstractStorage`, changes. Instead of sending messages to the queue for later processing as described in steps 3–5 of the previous example, these entities are written directly to Redis or Elasticsearch during the same PHP process.

This approach uses `DirectSynchronizationConsolePlugin`, which leverages Symfony&apos;s `onTerminate` event to perform the final synchronization step after the console command completes execution.

For details on configuring direct sync, see [Configure direct synchronize](/docs/dg/dev/backend-development/data-manipulation/data-publishing/configurartion/configure-direct-synchronize).

## Data architecture

P&amp;S supports intelligent solutions and scalable architecture designs by handling data denormalization and distribution across Spryker Storefronts and APIs.

### Denormalization and distribution

- Denormalization prepares data in the format required by the consuming clients, such as storefronts or APIs.

- Distribution ensures that this data is moved closer to end users, enabling fast and responsive access that feels like interacting with a local store.

#### Project examples of data denormalization and distribution

Several Spryker partners leverage P&amp;S to distribute product data to warehouse picking devices, such as barcode scanners. These devices access the product catalog as if it were local, allowing them to function even with poor or no network connectivity.

In other implementations, P&amp;S enables businesses to centralize sensitive customer data - such as in Germany for compliance reasons - while distributing localized catalogs globally. For example, buyers in Brazil can browse the catalog with minimal latency, as if the data were hosted locally.


### Architectural considerations

When designing a solution that incorporates P&amp;S, consider the following:

- Eventual consistency of data in storefronts and client applications  

- Horizontal scalability of the publish process (supported natively) and the synchronization process (may require custom development)  

- Data object limitations, including payload sizes and system constraints

### Data object limitations

To ensure system stability, it is critical to define and enforce appropriate non-functional requirements for P&amp;S, such as the following:

- The maximum size of a storage synchronization message should not exceed 256 KB. This prevents processing issues and ensures that API consumers can reliably receive data without encountering failures because of large payloads.

- Avoid exceeding request limits for storage, such as Redis, and search systems, such as OpenSearch, during the synchronization process.

As with any non-functional requirements, you can adapt these constraints based on project needs. However, this may require a custom implementation or refactoring Spryker&apos;s default functionality.

For example, if your project must support sending API payloads larger than 10 MB - an uncommon scenario for e-commerce platforms - it is still achievable with Spryker. However, this requires a thorough review of the business logic tied to the relevant API endpoints and adjustments to support larger objects.
</description>
            <pubDate>Thu, 10 Sep 2026 08:29:18 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/backend-development/data-manipulation/data-publishing/publish-and-synchronization.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/backend-development/data-manipulation/data-publishing/publish-and-synchronization.html</guid>
            
            
        </item>
        
        <item>
            <title>Preparing for heavy loads and traffic</title>
            <description>This document helps you prepare for a traditionally very busy season of the year: Black Friday, Cyber Monday, and the Holiday Season but it helps you whenever you expect your shop to receive record-breaking traffic. In this document, you can find recommendations written for business decision-makers, hosting providers, and Spryker developers. So feel free to forward our recommendations to your colleagues.

## Business tips

- Prepare your customer care to handle non-technical issues. As higher amounts of transactions result in a higher number of customer support requests.
- Know your customer: global businesses have Black Friday starts much earlier for eastern time zones and ends much later for western time zones.
- Plan your features in advance: deliver something just before the campaign increases your risks.

## DevOps and hosting tips

- Follow [General performance guidelines](/docs/dg/dev/guidelines/performance-guidelines/general-performance-guidelines.html)
- Prepare stand-by/hot-spare compute nodes. Buy it in advance.
- Prepare sizing of Key-value store (Redis or Valkey)/ElasticSeach/Database services.
- Make sure you have clear procedures for adding a new compute node to your cluster and removing one from it. It is good to have it fully automated allowing you to easily change your cluster configuration.
- Make sure content delivery services are in place to deliver images or other static binary data.
- Make sure [correct caching headers are set for static content](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching).
- Consider configuring HTTP2 and response compression.
- Global business: co-locate infrastructure and your customers.
- Make sure infrastructure monitoring is in place so you can watch for errors or issues.
- Test your deployment: you should be able to quickly deliver fixes if needed.
- If your project is hosted with Spryker PaaS, let us know that you are expecting a higher load using the [Support Hub](/docs/about/all/support/using-the-support-hub.html#announce-high-trafficload)

## Tips for developers

- Follow [General performance guidelines](/docs/dg/dev/guidelines/performance-guidelines/general-performance-guidelines.html)
- Disable features, that might have no big value during Black Friday but add additional overhead:
- Persistent Cart
- Evaluate project features for the same reason
- Make sure that there are no Yves pages executing multiple Zed requests. The best case is 0 or max 1 call per request, but not on each page load
- Evaluate your code: maybe there is somewhere too verbose logging, which is not so useful but adds overhead
- Check your integration processes:
  - Asynchronous must handle expected amounts of data
  - Synchronous must handle the expected amount of requests in the expected time per request
  - Make sure that your ERP or backend systems are capable of processing the expected number of transactions
  - Talk to partners integrated into checkout—for example, payment providers and fraud checks. They need to be prepared to handle expected volumes of transactions
  - Preload all relevant data in advanced: new products, prepare discount rules but mark them disabled
  - Make sure application monitoring is in place ([Tideways](/docs/pbc/all/miscellaneous/{{site.version}}/third-party-integrations/operational-tools-monitoring-legal/tideways.html), NewRelic) so you can watch for errors or issues

## Extra: Performance tips

- Determine the critical journey that your customers will follow:
- Journey before the checkout.
- Journey in the checkout (what are the most popular payment or shipping methods?).
- Prepare test plans and execute tests (different tools can be used: JMeter, LoadRunner, BlazeMeter).
- Make sure that test results match the expected load or analyze and optimize bottlenecks.
- Test also external systems to make sure they handle the expected load.
- Run a rehearsal: execute the tests with higher numbers than you expect and make sure you still have stability and room to handle all coming customers.
</description>
            <pubDate>Thu, 10 Sep 2026 08:29:18 +0000</pubDate>
            <link>https://docs.spryker.com/docs/about/all/support/preparing-for-heavy-loads-and-traffic.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/about/all/support/preparing-for-heavy-loads-and-traffic.html</guid>
            
            
        </item>
        
        <item>
            <title>Modules and application layers</title>
            <description>At Spryker, we use modular programming and packaging principles for organizing functionalities into independent software packages – modules.
To establish a common infrastructure across all modules and to assist configurability, flexibility, agility, and modularity, the modules are divided into application layers according to the Spryker&apos;s application design concept. Each application layer is further divided into layers following the layered architecture pattern.

## Layers

Layers are not limited to any specific application layer. However, in practice, there is a specific set of layers used by each application layer.

The Spryker layer structure looks as follows:

![Application layers and layers](https://spryker.s3.eu-central-1.amazonaws.com/docs/Developer+Guide/Architecture+Concepts/Modules+and+layers/layers.png)

Each layer serves a single purpose inside an application layer.

### Persistence layer

The *Persistence* layer is responsible for defining and dealing with the database in a module. Database table schemas and query objects are defined in this layer. The Persistence layer cannot access any other layer above it.

### Business layer

All the business logic is implemented in the *Business* layer. It usually has several business models to serve the necessary functionality. The Business Layer is located directly above the Persistence layer, so it can access it for the read and write operations.

### Communication layer

The *Communication* layer is the entry point of a module. When a frontend application communicates with the Commerce OS, it accesses the Communication layer first. Then, depending on the request functionality, the request is passed further from the Communication layer.

The Communication Layer is located above the Business layer, so it can access all the business logic in a module. That is how the Communication layer invokes the right business logic when requested.

### Presentation layer

On the *Presentation* layer, the view-related content is implemented. To get the needed data, the layer sends requests to the Communication layer. Then, it shows the data using the templates.

## Modularity

Modularity in Spryker refers to the platform&apos;s design philosophy of breaking down the system into independent, reusable components or modules. Each module encapsulates specific functionality, such as cart management, product search, or checkout processes, letting developers build, customize, and scale e-commerce solutions with greater flexibility and efficiency.

The following are recommendations on splitting functionality into modules:

1. Identify core business capabilities. Each capability can be a candidate for a module. For example: Product, Cart, Checkout. Break down your application into these high-level domains and assign each to a module.
2. Follow the single-responsibility principle (SRP). Each module should have a single responsibility and focus on one specific functionality. Avoid creating monolithic modules that handle multiple unrelated tasks. This ensures that modules remain lightweight, reusable, and easy to maintain.
3. Group related features together. If some features are closely related, group them into a single module. However, ensure that the module does not become too large or violate the SRP.
4. Separate cross-cutting concerns, such as logging, authentication, or caching, into their own modules. This approach ensures that these concerns are reusable across multiple modules.
5. Clearly define the boundaries of each module to avoid tight coupling. Modules should communicate with each other through well-defined interfaces, such as Facade, Client, Service, or Plugin.
6. Organize modules by layers: Persistence, Business, Communication and Presentation.
7. Avoid over-modularization. While modularity is beneficial, over-modularization can lead to unnecessary complexity. Avoid creating too many small modules that perform trivial tasks. Instead, focus on creating modules that encapsulate meaningful and reusable functionality.
8. Each module should be independently testable. Write functional or API tests for each module to ensure it works as expected. Use Spryker&apos;s testing tools and frameworks to streamline this process.
9. Reuse and enhance existing modules. Before creating a new module, check if Spryker or its ecosystem already provides a module that meets your needs. Reusing existing modules saves time and ensures compatibility with the platform.
</description>
            <pubDate>Thu, 10 Sep 2026 08:29:18 +0000</pubDate>
            <link>https://docs.spryker.com/docs/dg/dev/architecture/modules-and-application-layers.html</link>
            <guid isPermaLink="true">https://docs.spryker.com/docs/dg/dev/architecture/modules-and-application-layers.html</guid>
            
            
        </item>
        
    </channel>
</rss>
