diff --git a/core/core.services.yml b/core/core.services.yml
index 064a13ad14..4838361a38 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -336,8 +336,13 @@ services:
   config.storage.staging:
     class: Drupal\Core\Config\FileStorage
     factory: Drupal\Core\Config\FileStorageFactory::getSync
+  config.storage.export_sync.manager:
+    class: Drupal\Core\Config\ExportStorageSyncManager
+    arguments: ['@entity_type.manager']
+    public: false
   config.storage.sync:
-    alias: config.storage.staging
+    class: Drupal\Core\Config\FileStorage
+    factory: ['@config.storage.export_sync.manager', 'getSyncStorage']
   config.storage.snapshot:
     class: Drupal\Core\Config\DatabaseStorage
     arguments: ['@database', config_snapshot]
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php
index 454d515718..2d7f945c32 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php
@@ -48,6 +48,8 @@ class ConfigEntityType extends EntityType implements ConfigEntityTypeInterface {
    */
   protected $mergedConfigExport = [];
 
+  protected $config_shards = [];
+
   /**
    * {@inheritdoc}
    *
@@ -188,4 +190,7 @@ public function getLookupKeys() {
     return $this->lookup_keys;
   }
 
+  public function getShards() {
+    return $this->config_shards;
+  }
 }
diff --git a/core/lib/Drupal/Core/Config/ExportStorageSyncManager.php b/core/lib/Drupal/Core/Config/ExportStorageSyncManager.php
new file mode 100644
index 0000000000..3166a726ad
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/ExportStorageSyncManager.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\Core\Config;
+
+
+use Drupal\Core\Config\Entity\ConfigEntityType;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+
+class ExportStorageSyncManager {
+
+  /**
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
+    $this->entityTypeManager = $entity_type_manager;
+  }
+
+  public function getSyncStorage() {
+    $shard_list = [];
+    foreach ($this->entityTypeManager->getDefinitions() as $entity_type) {
+      if ($entity_type instanceof ConfigEntityType && ($shards = $entity_type->getShards())) {
+        $shard_list[$entity_type->getConfigPrefix()] = $shards;
+      }
+    }
+    return FileStorageFactory::getSync()->setShardList($shard_list);
+  }
+
+
+}
diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php
index 26e434a67f..b307d4fdbe 100644
--- a/core/lib/Drupal/Core/Config/FileStorage.php
+++ b/core/lib/Drupal/Core/Config/FileStorage.php
@@ -5,6 +5,7 @@
 use Drupal\Component\FileCache\FileCacheFactory;
 use Drupal\Component\FileSecurity\FileSecurity;
 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\File\FileSystemInterface;
 use Drupal\Core\Serialization\Yaml;
 
@@ -34,6 +35,16 @@ class FileStorage implements StorageInterface {
    */
   protected $fileCache;
 
+  /**
+   * @var array
+   */
+  protected $shardList;
+
+  /**
+   * @var string
+   */
+  protected $shardRegexp;
+
   /**
    * Constructs a new FileStorage.
    *
@@ -110,6 +121,33 @@ public function read($name) {
       return $data;
     }
 
+    $data = $this->doRead($filepath, $name);
+    $dir = $this->getCollectionDirectory();
+    $files = scandir($dir);
+    $pattern = '/^' . preg_quote(basename($filepath) . '.shard.', '/') . '(.*)' . '/';
+    foreach ($files as $file) {
+      if ($file[0] !== '.' && preg_match($pattern, $file, $matches)) {
+        $shard_data = $this->doRead($dir . '/' . $file, $name . '.shard.' . $matches[1]);
+        NestedArray::setValue($data, explode('.', $matches[1]), $shard_data);
+      }
+    }
+
+    $this->fileCache->set($filepath, $data);
+
+    return $data;
+  }
+
+  /**
+   * Read a file and return decoded data.
+   *
+   * @param string $filepath
+   *   The file to read
+   * @param string $name
+   *   Name of the config object, only used for error message.
+   *
+   * @return array
+   */
+  protected function doRead($filepath, $name) {
     $data = file_get_contents($filepath);
     try {
       $data = $this->decode($data);
@@ -117,8 +155,6 @@ public function read($name) {
     catch (InvalidDataTypeException $e) {
       throw new UnsupportedDataTypeConfigException('Invalid data type in config ' . $name . ', found in file' . $filepath . ' : ' . $e->getMessage());
     }
-    $this->fileCache->set($filepath, $data);
-
     return $data;
   }
 
@@ -135,10 +171,40 @@ public function readMultiple(array $names) {
     return $list;
   }
 
+  public function setShardList(array $shard_list) {
+    if ($this->shardList = $shard_list) {
+      $this->shardRegexp = '/^(' . implode('|', array_keys($shard_list)) . ')/';
+    }
+    return $this;
+  }
+
   /**
    * {@inheritdoc}
    */
   public function write($name, array $data) {
+    $target = $this->getFilePath($name);
+    if ($this->shardRegexp && preg_match($this->shardRegexp, $name, $matches)) {
+      foreach (($this->shardList[$matches[1]] ?? []) as $shard_key) {
+        $shard_data = NestedArray::getValue($data, explode('.', $shard_key));
+        foreach ($shard_data as $config_key => $config_data) {
+          $postfix = ".shard.$shard_key.$config_key";
+          $this->doWrite($target . $postfix, $config_data, $name . $postfix);
+          unset($data[$shard_key]);
+
+        }
+      }
+    }
+    $this->doWrite($target, $data, $name);
+
+    return TRUE;
+  }
+
+  /**
+   * @param string $target
+   * @param array $data
+   * @param string $name
+   */
+  protected function doWrite($target, array $data, $name) {
     try {
       $encoded_data = $this->encode($data);
     }
@@ -146,7 +212,6 @@ public function write($name, array $data) {
       throw new StorageException("Invalid data type in config $name: {$e->getMessage()}");
     }
 
-    $target = $this->getFilePath($name);
     $status = @file_put_contents($target, $encoded_data);
     if ($status === FALSE) {
       // Try to make sure the directory exists and try writing again.
@@ -161,8 +226,6 @@ public function write($name, array $data) {
     }
 
     $this->fileCache->set($target, $data);
-
-    return TRUE;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
index 00800b5839..5f37c5c3d3 100644
--- a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
+++ b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php
@@ -32,6 +32,9 @@
  *     "mode",
  *     "content",
  *     "hidden",
+ *   },
+ *   config_shards = {
+ *     "content"
  *   }
  * )
  */
