Index: vendor/magento/module-directory-graph-ql/Model/Cache/Tag/Strategy/Config/CountryTagGenerator.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-directory-graph-ql/Model/Cache/Tag/Strategy/Config/CountryTagGenerator.php b/vendor/magento/module-directory-graph-ql/Model/Cache/Tag/Strategy/Config/CountryTagGenerator.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-directory-graph-ql/Model/Cache/Tag/Strategy/Config/CountryTagGenerator.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\DirectoryGraphQl\Model\Cache\Tag\Strategy\Config;
+
+use Magento\DirectoryGraphQl\Model\Resolver\Country\Identity;
+use Magento\Framework\App\Config\ValueInterface;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\Store\Model\Config\Cache\Tag\Strategy\TagGeneratorInterface;
+
+/**
+ * Generator that generates cache tags for country configuration
+ */
+class CountryTagGenerator implements TagGeneratorInterface
+{
+    /**
+     * @var string[]
+     */
+    private $countryConfigPaths = [
+        'general/locale/code',
+        'general/country/allow'
+    ];
+
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @param StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        StoreManagerInterface $storeManager
+    ) {
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function generateTags(ValueInterface $config): array
+    {
+        if (in_array($config->getPath(), $this->countryConfigPaths)) {
+            if ($config->getScope() == ScopeInterface::SCOPE_WEBSITES) {
+                $website = $this->storeManager->getWebsite($config->getScopeId());
+                $storeIds = $website->getStoreIds();
+            } elseif ($config->getScope() == ScopeInterface::SCOPE_STORES) {
+                $storeIds = [$config->getScopeId()];
+            } else {
+                $storeIds = array_keys($this->storeManager->getStores());
+            }
+            $tags = [];
+            foreach ($storeIds as $storeId) {
+                $tags[] = sprintf('%s_%s', Identity::CACHE_TAG, $storeId);
+            }
+            return $tags;
+        }
+        return [];
+    }
+}
Index: vendor/magento/module-directory-graph-ql/Model/Cache/Tag/Strategy/Config/CurrencyTagGenerator.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-directory-graph-ql/Model/Cache/Tag/Strategy/Config/CurrencyTagGenerator.php b/vendor/magento/module-directory-graph-ql/Model/Cache/Tag/Strategy/Config/CurrencyTagGenerator.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-directory-graph-ql/Model/Cache/Tag/Strategy/Config/CurrencyTagGenerator.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\DirectoryGraphQl\Model\Cache\Tag\Strategy\Config;
+
+use Magento\DirectoryGraphQl\Model\Resolver\Currency\Identity;
+use Magento\Framework\App\Config\ValueInterface;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\Store\Model\Config\Cache\Tag\Strategy\TagGeneratorInterface;
+
+/**
+ * Generator that generates cache tags for currency configuration
+ */
+class CurrencyTagGenerator implements TagGeneratorInterface
+{
+    /**
+     * @var string[]
+     */
+    private $currencyConfigPaths = [
+        'currency/options/base',
+        'currency/options/default',
+        'currency/options/allow',
+        'currency/options/customsymbol'
+    ];
+
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @param StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        StoreManagerInterface $storeManager
+    ) {
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function generateTags(ValueInterface $config): array
+    {
+        if (in_array($config->getPath(), $this->currencyConfigPaths)) {
+            if ($config->getScope() == ScopeInterface::SCOPE_WEBSITES) {
+                $website = $this->storeManager->getWebsite($config->getScopeId());
+                $storeIds = $website->getStoreIds();
+            } elseif ($config->getScope() == ScopeInterface::SCOPE_STORES) {
+                $storeIds = [$config->getScopeId()];
+            } else {
+                $storeIds = array_keys($this->storeManager->getStores());
+            }
+            $tags = [];
+            foreach ($storeIds as $storeId) {
+                $tags[] = sprintf('%s_%s', Identity::CACHE_TAG, $storeId);
+            }
+            return $tags;
+        }
+        return [];
+    }
+}
Index: vendor/magento/module-directory-graph-ql/Model/Resolver/Country/Identity.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-directory-graph-ql/Model/Resolver/Country/Identity.php b/vendor/magento/module-directory-graph-ql/Model/Resolver/Country/Identity.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-directory-graph-ql/Model/Resolver/Country/Identity.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\DirectoryGraphQl\Model\Resolver\Country;
+
+use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
+use Magento\Store\Model\StoreManagerInterface;
+
+class Identity implements IdentityInterface
+{
+    /**
+     * @var string
+     */
+    public const CACHE_TAG = 'gql_country';
+
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @param StoreManagerInterface $storeManager
+     */
+    public function __construct(StoreManagerInterface $storeManager)
+    {
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getIdentities(array $resolvedData): array
+    {
+        if (empty($resolvedData)) {
+            return [];
+        }
+        $storeId = $this->storeManager->getStore()->getId();
+        return [self::CACHE_TAG, sprintf('%s_%s', self::CACHE_TAG, $storeId)];
+    }
+}
Index: vendor/magento/module-directory-graph-ql/Model/Resolver/Currency/Identity.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-directory-graph-ql/Model/Resolver/Currency/Identity.php b/vendor/magento/module-directory-graph-ql/Model/Resolver/Currency/Identity.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-directory-graph-ql/Model/Resolver/Currency/Identity.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\DirectoryGraphQl\Model\Resolver\Currency;
+
+use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
+use Magento\Store\Model\StoreManagerInterface;
+
+class Identity implements IdentityInterface
+{
+    /**
+     * @var string
+     */
+    public const CACHE_TAG = 'gql_currency';
+
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @param StoreManagerInterface $storeManager
+     */
+    public function __construct(StoreManagerInterface $storeManager)
+    {
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getIdentities(array $resolvedData): array
+    {
+        if (empty($resolvedData)) {
+            return [];
+        }
+        $storeId = $this->storeManager->getStore()->getId();
+        return [self::CACHE_TAG, sprintf('%s_%s', self::CACHE_TAG, $storeId)];
+    }
+}
Index: vendor/magento/module-directory-graph-ql/Plugin/Currency.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-directory-graph-ql/Plugin/Currency.php b/vendor/magento/module-directory-graph-ql/Plugin/Currency.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-directory-graph-ql/Plugin/Currency.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\DirectoryGraphQl\Plugin;
+
+use Magento\DirectoryGraphQl\Model\Resolver\Currency\Identity;
+use Magento\Framework\DataObject\IdentityInterface;
+use Magento\Framework\Event\ManagerInterface;
+use Magento\Directory\Model\Currency as CurrencyModel;
+
+/**
+ * Currency plugin triggers clean page cache and provides currency cache identities
+ */
+class Currency implements IdentityInterface
+{
+    /**
+     * Application Event Dispatcher
+     *
+     * @var ManagerInterface
+     */
+    private $eventManager;
+
+    /**
+     * @param ManagerInterface $eventManager
+     */
+    public function __construct(ManagerInterface $eventManager)
+    {
+        $this->eventManager = $eventManager;
+    }
+
+    /**
+     * Trigger clean cache by tags after save rates
+     *
+     * @param CurrencyModel $subject
+     * @param CurrencyModel $result
+     * @return CurrencyModel
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterSaveRates(CurrencyModel $subject, CurrencyModel $result): CurrencyModel
+    {
+        $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this]);
+        return $result;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getIdentities()
+    {
+        return [Identity::CACHE_TAG];
+    }
+}
Index: vendor/magento/module-directory-graph-ql/etc/di.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-directory-graph-ql/etc/di.xml b/vendor/magento/module-directory-graph-ql/etc/di.xml
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-directory-graph-ql/etc/di.xml	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Store\Model\Config\Cache\Tag\Strategy\CompositeTagGenerator">
+        <arguments>
+            <argument name="tagGenerators" xsi:type="array">
+                <item name="currency_tag_generator" xsi:type="object">
+                    Magento\DirectoryGraphQl\Model\Cache\Tag\Strategy\Config\CurrencyTagGenerator
+                </item>
+                <item name="country_tag_generator" xsi:type="object">
+                    Magento\DirectoryGraphQl\Model\Cache\Tag\Strategy\Config\CountryTagGenerator
+                </item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Directory\Model\Currency">
+        <plugin name="afterSaveRate" type="Magento\DirectoryGraphQl\Plugin\Currency" />
+    </type>
+</config>
Index: vendor/magento/module-directory-graph-ql/etc/schema.graphqls
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-directory-graph-ql/etc/schema.graphqls b/vendor/magento/module-directory-graph-ql/etc/schema.graphqls
--- a/vendor/magento/module-directory-graph-ql/etc/schema.graphqls	(revision fc35000d1dc61dbf65b0f8f49b802074073686a7)
+++ b/vendor/magento/module-directory-graph-ql/etc/schema.graphqls	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -2,9 +2,9 @@
 # See COPYING.txt for license details.
 
 type Query {
-    currency: Currency @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Currency") @doc(description: "Return information about the store's currency.") @cache(cacheable: false)
-    countries: [Country] @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Countries") @doc(description: "The countries query provides information for all countries.") @cache(cacheable: false)
-    country (id: String): Country @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Country") @doc(description: "The countries query provides information for a single country.") @cache(cacheable: false)
+    currency: Currency @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Currency") @doc(description: "Return information about the store's currency.") @cache(cacheIdentity: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Currency\\Identity")
+    countries: [Country] @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Countries") @doc(description: "The countries query provides information for all countries.") @cache(cacheIdentity: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Country\\Identity")
+    country (id: String): Country @resolver(class: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Country") @doc(description: "The countries query provides information for a single country.") @cache(cacheIdentity: "Magento\\DirectoryGraphQl\\Model\\Resolver\\Country\\Identity")
 }
 
 type Currency {
Index: vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/CompositeTagGenerator.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/CompositeTagGenerator.php b/vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/CompositeTagGenerator.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/CompositeTagGenerator.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\Store\Model\Config\Cache\Tag\Strategy;
+
+use Magento\Framework\App\Config\ValueInterface;
+
+/**
+ * Composite tag generator that generates cache tags for store configurations.
+ */
+class CompositeTagGenerator implements TagGeneratorInterface
+{
+    /**
+     * @var TagGeneratorInterface[]
+     */
+    private $tagGenerators;
+
+    /**
+     * @param TagGeneratorInterface[] $tagGenerators
+     */
+    public function __construct(
+        array $tagGenerators
+    ) {
+        $this->tagGenerators = $tagGenerators;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function generateTags(ValueInterface $config): array
+    {
+        $tagsArray = [];
+        foreach ($this->tagGenerators as $tagGenerator) {
+            $tagsArray[] = $tagGenerator->generateTags($config);
+        }
+        return array_merge(...$tagsArray);
+    }
+}
Index: vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/StoreConfig.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/StoreConfig.php b/vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/StoreConfig.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/StoreConfig.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\Store\Model\Config\Cache\Tag\Strategy;
+
+use Magento\Framework\App\Cache\Tag\StrategyInterface;
+use Magento\Framework\App\Config\ValueInterface;
+
+/**
+ * Produce cache tags for store config.
+ */
+class StoreConfig implements StrategyInterface
+{
+    /**
+     * @var TagGeneratorInterface
+     */
+    private $tagGenerator;
+
+    /**
+     * @param TagGeneratorInterface $tagGenerator
+     */
+    public function __construct(
+        TagGeneratorInterface $tagGenerator
+    ) {
+        $this->tagGenerator = $tagGenerator;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getTags($object): array
+    {
+        if (!is_object($object)) {
+            throw new \InvalidArgumentException('Provided argument is not an object');
+        }
+
+        if ($object instanceof ValueInterface && $object->isValueChanged()) {
+            return $this->tagGenerator->generateTags($object);
+        }
+
+        return [];
+    }
+}
Index: vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/TagGeneratorInterface.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/TagGeneratorInterface.php b/vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/TagGeneratorInterface.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store/Model/Config/Cache/Tag/Strategy/TagGeneratorInterface.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\Store\Model\Config\Cache\Tag\Strategy;
+
+use Magento\Framework\App\Config\ValueInterface;
+
+/**
+ * Store configuration cache tag generator interface
+ */
+interface TagGeneratorInterface
+{
+    /**
+     * Generate cache tags with given store configuration
+     *
+     * @param ValueInterface $config
+     * @return array
+     */
+    public function generateTags(ValueInterface $config): array;
+}
Index: vendor/magento/module-store/etc/di.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store/etc/di.xml b/vendor/magento/module-store/etc/di.xml
--- a/vendor/magento/module-store/etc/di.xml	(revision fc35000d1dc61dbf65b0f8f49b802074073686a7)
+++ b/vendor/magento/module-store/etc/di.xml	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -457,4 +457,20 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\App\Cache\Tag\Strategy\Factory">
+        <arguments>
+            <argument name="customStrategies" xsi:type="array">
+                <item name="Magento\Framework\App\Config\ValueInterface" xsi:type="object">
+                    Magento\Store\Model\Config\Cache\Tag\Strategy\StoreConfig
+                </item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Store\Model\Config\Cache\Tag\Strategy\StoreConfig">
+        <arguments>
+            <argument name="tagGenerator" xsi:type="object">
+                Magento\Store\Model\Config\Cache\Tag\Strategy\CompositeTagGenerator
+            </argument>
+        </arguments>
+    </type>
 </config>
Index: vendor/magento/module-store-graph-ql/Model/Cache/Tag/Strategy/ConfigTagGenerator.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store-graph-ql/Model/Cache/Tag/Strategy/ConfigTagGenerator.php b/vendor/magento/module-store-graph-ql/Model/Cache/Tag/Strategy/ConfigTagGenerator.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store-graph-ql/Model/Cache/Tag/Strategy/ConfigTagGenerator.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\StoreGraphQl\Model\Cache\Tag\Strategy;
+
+use Magento\Framework\App\Config\ValueInterface;
+use Magento\Store\Model\Config\Cache\Tag\Strategy\TagGeneratorInterface;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity;
+
+/**
+ * Generator that generates cache tags for store configuration.
+ */
+class ConfigTagGenerator implements TagGeneratorInterface
+{
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @param StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        StoreManagerInterface $storeManager
+    ) {
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function generateTags(ValueInterface $config): array
+    {
+        if ($config->getScope() == ScopeInterface::SCOPE_WEBSITES) {
+            $website = $this->storeManager->getWebsite($config->getScopeId());
+            $storeIds = $website->getStoreIds();
+        } elseif ($config->getScope() == ScopeInterface::SCOPE_STORES) {
+            $storeIds = [$config->getScopeId()];
+        } else {
+            $storeIds = array_keys($this->storeManager->getStores());
+        }
+        $tags = [];
+        foreach ($storeIds as $storeId) {
+            $tags[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $storeId);
+        }
+        return $tags;
+    }
+}
Index: vendor/magento/module-store-graph-ql/Model/Resolver/Store/ConfigIdentity.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store-graph-ql/Model/Resolver/Store/ConfigIdentity.php b/vendor/magento/module-store-graph-ql/Model/Resolver/Store/ConfigIdentity.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store-graph-ql/Model/Resolver/Store/ConfigIdentity.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\StoreGraphQl\Model\Resolver\Store;
+
+use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
+
+class ConfigIdentity implements IdentityInterface
+{
+    /**
+     * @var string
+     */
+    public const CACHE_TAG = 'gql_store_config';
+
+    /**
+     * @inheritDoc
+     */
+    public function getIdentities(array $resolvedData): array
+    {
+        if (!isset($resolvedData['id'])) {
+            return [];
+        }
+        return [self::CACHE_TAG, sprintf('%s_%s', self::CACHE_TAG, $resolvedData['id'])];
+    }
+}
Index: vendor/magento/module-store-graph-ql/Model/Resolver/Stores/ConfigIdentity.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store-graph-ql/Model/Resolver/Stores/ConfigIdentity.php b/vendor/magento/module-store-graph-ql/Model/Resolver/Stores/ConfigIdentity.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store-graph-ql/Model/Resolver/Stores/ConfigIdentity.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\StoreGraphQl\Model\Resolver\Stores;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity as StoreConfigIdentity;
+
+class ConfigIdentity implements IdentityInterface
+{
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @param StoreManagerInterface $storeManager
+     */
+    public function __construct(StoreManagerInterface $storeManager)
+    {
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public function getIdentities(array $resolvedData): array
+    {
+        $ids = [];
+        foreach ($resolvedData as $storeConfig) {
+            $ids[] = sprintf('%s_%s', StoreConfigIdentity::CACHE_TAG, $storeConfig['id']);
+        }
+        if (!empty($resolvedData)) {
+            $websiteId = $resolvedData[0]['website_id'];
+            $currentStoreGroupId = $this->getCurrentStoreGroupId($resolvedData);
+            $groupTag = $currentStoreGroupId ? 'group_' . $currentStoreGroupId : '';
+            $ids[] = sprintf('%s_%s', StoreConfigIdentity::CACHE_TAG, 'website_' . $websiteId . $groupTag);
+        }
+
+        return empty($ids) ? [] : array_merge([StoreConfigIdentity::CACHE_TAG], $ids);
+    }
+
+    /**
+     * Return current store group id if it is certain that useCurrentGroup is true in the query
+     *
+     * @param array $resolvedData
+     * @return string|int|null
+     */
+    private function getCurrentStoreGroupId(array $resolvedData)
+    {
+        $storeGroupCodes = array_unique(array_column($resolvedData, 'store_group_code'));
+        if (count($storeGroupCodes) == 1) {
+            try {
+                $store = $this->storeManager->getStore($resolvedData[0]['id']);
+                if ($store->getWebsite()->getGroupCollection()->count() != 1) {
+                    // There are multiple store groups in the website while there is only one store group
+                    // in the resolved data. Therefore useCurrentGroup must be true in the query
+                    return $store->getStoreGroupId();
+                }
+            } catch (NoSuchEntityException $e) {
+                // Do nothing
+                ;
+            }
+        }
+        return null;
+    }
+}
Index: vendor/magento/module-store-graph-ql/Plugin/Group.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store-graph-ql/Plugin/Group.php b/vendor/magento/module-store-graph-ql/Plugin/Group.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store-graph-ql/Plugin/Group.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\StoreGraphQl\Plugin;
+
+use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity;
+
+/**
+ * Store group plugin to provide identities for cache invalidation
+ */
+class Group
+{
+    /**
+     * Add graphql store config tag to the store group cache identities.
+     *
+     * @param \Magento\Store\Model\Group $subject
+     * @param array $result
+     * @return array
+     */
+    public function afterGetIdentities(\Magento\Store\Model\Group $subject, array $result): array
+    {
+        $storeIds = $subject->getStoreIds();
+        if (count($storeIds) > 0) {
+            foreach ($storeIds as $storeId) {
+                $result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $storeId);
+            }
+            $origWebsiteId = $subject->getOrigData('website_id');
+            $websiteId = $subject->getWebsiteId();
+            if ($origWebsiteId != $websiteId) { // Add or switch to a new website
+                $result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, 'website_' . $websiteId);
+            }
+        }
+
+        return $result;
+    }
+}
Index: vendor/magento/module-store-graph-ql/Plugin/Store.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store-graph-ql/Plugin/Store.php b/vendor/magento/module-store-graph-ql/Plugin/Store.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store-graph-ql/Plugin/Store.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\StoreGraphQl\Plugin;
+
+use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity;
+
+/**
+ * Store plugin to provide identities for cache invalidation
+ */
+class Store
+{
+    /**
+     * Add graphql store config tag to the store cache identities.
+     *
+     * @param \Magento\Store\Model\Store $subject
+     * @param array $result
+     * @return array
+     */
+    public function afterGetIdentities(\Magento\Store\Model\Store $subject, array $result): array
+    {
+        $result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $subject->getId());
+
+        $isActive = $subject->getIsActive();
+        // New active store or newly activated store or an active store switched store group
+        if ($isActive
+            && ($subject->getOrigData('is_active') !== $isActive || $this->isStoreGroupSwitched($subject))
+        ) {
+            $websiteId = $subject->getWebsiteId();
+            if ($websiteId !== null) {
+                $result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, 'website_' . $websiteId);
+                $storeGroupId = $subject->getStoreGroupId();
+                if ($storeGroupId !== null) {
+                    $result[] = sprintf(
+                        '%s_%s',
+                        ConfigIdentity::CACHE_TAG,
+                        'website_' . $websiteId . 'group_' . $storeGroupId
+                    );
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Check whether the store group of the store is switched
+     *
+     * @param \Magento\Store\Model\Store $store
+     * @return bool
+     */
+    private function isStoreGroupSwitched(\Magento\Store\Model\Store $store): bool
+    {
+        $origStoreGroupId = $store->getOrigData('group_id');
+        $storeGroupId = $store->getStoreGroupId();
+        return $origStoreGroupId != null && $origStoreGroupId != $storeGroupId;
+    }
+}
Index: vendor/magento/module-store-graph-ql/Plugin/Website.php
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store-graph-ql/Plugin/Website.php b/vendor/magento/module-store-graph-ql/Plugin/Website.php
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store-graph-ql/Plugin/Website.php	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+declare(strict_types=1);
+
+namespace Magento\StoreGraphQl\Plugin;
+
+use Magento\StoreGraphQl\Model\Resolver\Store\ConfigIdentity;
+
+/**
+ * Website plugin to provide identities for cache invalidation
+ */
+class Website
+{
+    /**
+     * Add graphql store config tag to the website cache identities.
+     *
+     * @param \Magento\Store\Model\Website $subject
+     * @param array $result
+     * @return array
+     */
+    public function afterGetIdentities(\Magento\Store\Model\Website $subject, array $result): array
+    {
+        $storeIds = $subject->getStoreIds();
+        foreach ($storeIds as $storeId) {
+            $result[] = sprintf('%s_%s', ConfigIdentity::CACHE_TAG, $storeId);
+        }
+        return $result;
+    }
+}
Index: vendor/magento/module-store-graph-ql/etc/di.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store-graph-ql/etc/di.xml b/vendor/magento/module-store-graph-ql/etc/di.xml
new file mode 100644
--- /dev/null	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
+++ b/vendor/magento/module-store-graph-ql/etc/di.xml	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Store\Model\Config\Cache\Tag\Strategy\CompositeTagGenerator">
+        <arguments>
+            <argument name="tagGenerators" xsi:type="array">
+                <item name="store_config_tag_generator" xsi:type="object">
+                    Magento\StoreGraphQl\Model\Cache\Tag\Strategy\ConfigTagGenerator
+                </item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Store\Model\Store">
+        <plugin name="getStoreIdentities" type="Magento\StoreGraphQl\Plugin\Store" />
+    </type>
+    <type name="Magento\Store\Model\Website">
+        <plugin name="getWebsiteIdentities" type="Magento\StoreGraphQl\Plugin\Website" />
+    </type>
+    <type name="Magento\Store\Model\Group">
+        <plugin name="getGroupIdentities" type="Magento\StoreGraphQl\Plugin\Group" />
+    </type>
+</config>
Index: vendor/magento/module-store-graph-ql/etc/schema.graphqls
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/vendor/magento/module-store-graph-ql/etc/schema.graphqls b/vendor/magento/module-store-graph-ql/etc/schema.graphqls
--- a/vendor/magento/module-store-graph-ql/etc/schema.graphqls	(revision fc35000d1dc61dbf65b0f8f49b802074073686a7)
+++ b/vendor/magento/module-store-graph-ql/etc/schema.graphqls	(revision 1c05bb0ac1970f056e159f4396b154f5a6187892)
@@ -1,10 +1,10 @@
 # Copyright © Magento, Inc. All rights reserved.
 # See COPYING.txt for license details.
 type Query {
-    storeConfig : StoreConfig @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\StoreConfigResolver") @doc(description: "Return details about the store's configuration.") @cache(cacheable: false)
+    storeConfig : StoreConfig @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\StoreConfigResolver") @doc(description: "Return details about the store's configuration.") @cache(cacheIdentity: "Magento\\StoreGraphQl\\Model\\Resolver\\Store\\ConfigIdentity")
     availableStores(
         useCurrentGroup: Boolean @doc(description: "Filter store views by the current store group.")
-    ): [StoreConfig] @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\AvailableStoresResolver") @doc(description: "Get a list of available store views and their config information.")
+    ): [StoreConfig] @resolver(class: "Magento\\StoreGraphQl\\Model\\Resolver\\AvailableStoresResolver") @doc(description: "Get a list of available store views and their config information.") @cache(cacheIdentity: "Magento\\StoreGraphQl\\Model\\Resolver\\Stores\\ConfigIdentity")
 }
 
 type Website @doc(description: "Deprecated. It should not be used on the storefront. Contains information about a website.") {
