diff --git a/core/lib/Drupal/Core/Update/UpdateBackend.php b/core/lib/Drupal/Core/Update/UpdateBackend.php
new file mode 100644
index 0000000000000000000000000000000000000000..3101093b5894c84f10729e7e3f308a639c4615ac
--- /dev/null
+++ b/core/lib/Drupal/Core/Update/UpdateBackend.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Drupal\Core\Update;
+
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Cache\NullBackend;
+
+/**
+ * Defines a cache backend for use during Drupal database updates.
+ *
+ * Passes on deletes to another backend while extending the NullBackend to avoid
+ * using anything cached prior to running updates.
+ */
+class UpdateBackend extends NullBackend {
+
+  /**
+   * The regular runtime cache backend.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface
+   */
+  protected $backend;
+
+  /**
+   * UpdateBackend constructor.
+   *
+   * @param \Drupal\Core\Cache\CacheBackendInterface $backend
+   *   The regular runtime cache backend.
+   */
+  public function __construct(CacheBackendInterface $backend) {
+    $this->backend = $backend;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function delete($cid) {
+    $this->backend->delete($cid);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteMultiple(array $cids) {
+    $this->backend->deleteMultiple($cids);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll() {
+    $this->backend->deleteAll();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Update/UpdateCacheBackendFactory.php b/core/lib/Drupal/Core/Update/UpdateCacheBackendFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..1a459f3a0bd1d2224dc6135bac772b30d6b438ee
--- /dev/null
+++ b/core/lib/Drupal/Core/Update/UpdateCacheBackendFactory.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Drupal\Core\Update;
+
+use Drupal\Core\Cache\CacheFactoryInterface;
+
+/**
+ * Cache factory implementation for use during Drupal database updates.
+ *
+ * Decorates the regular runtime cache_factory service so that caches use
+ * \Drupal\Core\Update\UpdateBackend.
+ *
+ * @see \Drupal\Core\Update\UpdateServiceProvider::register()
+ */
+class UpdateCacheBackendFactory implements CacheFactoryInterface {
+
+  /**
+   * The regular runtime cache_factory service.
+   *
+   * @var \Drupal\Core\Cache\CacheFactoryInterface
+   */
+  protected $cacheFactory;
+
+  /**
+   * Instantiated update cache bins.
+   *
+   * @var \Drupal\Core\Update\UpdateBackend[]
+   */
+  protected $bins = [];
+
+  /**
+   * UpdateCacheBackendFactory constructor.
+   *
+   * @param \Drupal\Core\Cache\CacheFactoryInterface $cache_factory
+   *   The regular runtime cache_factory service.
+   */
+  public function __construct(CacheFactoryInterface $cache_factory) {
+    $this->cacheFactory = $cache_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function get($bin) {
+    if (!isset($this->bins[$bin])) {
+      $this->bins[$bin] = new UpdateBackend($this->cacheFactory->get($bin), $bin);
+    }
+    return $this->bins[$bin];
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Update/UpdateServiceProvider.php b/core/lib/Drupal/Core/Update/UpdateServiceProvider.php
index 22c9131eb381ca935dd2fa33ffa809cffab36526..7ac68e6b18e4aab9d5f475af94002d49a04d0098 100644
--- a/core/lib/Drupal/Core/Update/UpdateServiceProvider.php
+++ b/core/lib/Drupal/Core/Update/UpdateServiceProvider.php
@@ -19,8 +19,16 @@ class UpdateServiceProvider implements ServiceProviderInterface, ServiceModifier
    */
   public function register(ContainerBuilder $container) {
     $definition = new Definition('Drupal\Core\Cache\NullBackend', ['null']);
+    $definition->setDeprecated(TRUE, 'The "%service_id%\" service is deprecated. While updating Drupal all caches use \Drupal\Core\Update\UpdateBackend. See https://www.drupal.org/node/3066407');
     $container->setDefinition('cache.null', $definition);
 
+    // Decorate the cache factory in order to use
+    // \Drupal\Core\Update\UpdateBackend while running updates.
+    $container
+      ->register('update.cache_factory', UpdateCacheBackendFactory::class)
+      ->setDecoratedService('cache_factory')
+      ->addArgument(new Reference('update.cache_factory.inner'));
+
     $container->addCompilerPass(new UpdateCompilerPass(), PassConfig::TYPE_REMOVE, 128);
   }
 
@@ -28,25 +36,6 @@ public function register(ContainerBuilder $container) {
    * {@inheritdoc}
    */
   public function alter(ContainerBuilder $container) {
-    // Ensures for some services that they don't cache.
-    $null_cache_service = new Reference('cache.null');
-
-    $definition = $container->getDefinition('asset.resolver');
-    $definition->replaceArgument(5, $null_cache_service);
-
-    $definition = $container->getDefinition('library.discovery.collector');
-    $definition->replaceArgument(0, $null_cache_service);
-
-    $definition = $container->getDefinition('theme.registry');
-    $definition->replaceArgument(1, $null_cache_service);
-    $definition->replaceArgument(7, $null_cache_service);
-
-    $definition = $container->getDefinition('theme.initialization');
-    $definition->replaceArgument(2, $null_cache_service);
-
-    $definition = $container->getDefinition('plugin.manager.element_info');
-    $definition->replaceArgument(1, $null_cache_service);
-
     // Prevent the alias-based path processor, which requires a path_alias db
     // table, from being registered to the path processor manager. We do this by
     // removing the tags that the compiler pass looks for. This means the url
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 018d5d003ed740c0d189e32df2f26ceef1bdf752..218bc72442820c0829d11e2436ba797a347b0a9f 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1859,20 +1859,20 @@ function system_update_8011() {
  * Enable automated cron module and move the config into it.
  */
 function system_update_8013() {
-  $config_factory = \Drupal::configFactory();
-  $system_cron_config = $config_factory->getEditable('system.cron');
-  if ($autorun = $system_cron_config->get('threshold.autorun')) {
+  $autorun = \Drupal::configFactory()->getEditable('system.cron')->get('threshold.autorun');
+  if ($autorun) {
     // Install 'automated_cron' module.
     \Drupal::service('module_installer')->install(['automated_cron'], FALSE);
 
     // Copy 'autorun' value into the new module's 'interval' setting.
-    $config_factory->getEditable('automated_cron.settings')
+    \Drupal::configFactory()->getEditable('automated_cron.settings')
       ->set('interval', $autorun)
       ->save(TRUE);
   }
 
   // Remove the 'autorun' key in system module config.
-  $system_cron_config
+  \Drupal::configFactory()
+    ->getEditable('system.cron')
     ->clear('threshold.autorun')
     ->save(TRUE);
 }
diff --git a/core/modules/system/tests/src/Functional/Update/UpdateCacheTest.php b/core/modules/system/tests/src/Functional/Update/UpdateCacheTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d9765da4ddf17dca44dab0e2be4e50bb7d66262
--- /dev/null
+++ b/core/modules/system/tests/src/Functional/Update/UpdateCacheTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Drupal\Tests\system\Functional\Update;
+
+use Drupal\Core\Url;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\RequirementsPageTrait;
+
+/**
+ * Tests caches during updates.
+ *
+ * @group Update
+ */
+class UpdateCacheTest extends BrowserTestBase {
+  use RequirementsPageTrait;
+
+  /**
+   * Tests that caches are cleared during updates.
+   *
+   * @see \Drupal\Core\Update\UpdateServiceProvider
+   * @see \Drupal\Core\Update\UpdateBackend
+   */
+  public function testCaches() {
+    \Drupal::cache()->set('will_not_exist_after_update', TRUE);
+    // The site might be broken at the time so logging in using the UI might
+    // not work, so we use the API itself.
+    $this->writeSettings([
+      'settings' => [
+        'update_free_access' => (object) [
+          'value' => TRUE,
+          'required' => TRUE,
+        ],
+      ],
+    ]);
+
+    // Clicking continue should clear the caches.
+    $this->drupalGet(Url::fromRoute('system.db_update', [], ['path_processing' => FALSE]));
+    $this->updateRequirementsProblem();
+    $this->clickLink(t('Continue'));
+
+    $this->assertFalse(\Drupal::cache()->get('will_not_exist_after_update', FALSE));
+  }
+
+}