diff --git a/typo3/sysext/core/Classes/Core/Bootstrap.php b/typo3/sysext/core/Classes/Core/Bootstrap.php
index 655ee4fb4b4bfc86c15e8db0a9031e593d4d6c0e..a2f13f9393d5e3037566a0470284df09543697c1 100644
--- a/typo3/sysext/core/Classes/Core/Bootstrap.php
+++ b/typo3/sysext/core/Classes/Core/Bootstrap.php
@@ -26,8 +26,10 @@ use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Cache\Exception\InvalidBackendException;
 use TYPO3\CMS\Core\Cache\Exception\InvalidCacheException;
 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
+use TYPO3\CMS\Core\Cache\Frontend\PhpFrontend;
 use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend;
 use TYPO3\CMS\Core\Configuration\ConfigurationManager;
+use TYPO3\CMS\Core\DependencyInjection\Cache\ContainerBackend;
 use TYPO3\CMS\Core\DependencyInjection\ContainerBuilder;
 use TYPO3\CMS\Core\Imaging\IconRegistry;
 use TYPO3\CMS\Core\IO\PharStreamWrapperInterceptor;
@@ -111,6 +113,7 @@ class Bootstrap
         static::setMemoryLimit();
 
         $assetsCache = static::createCache('assets', $disableCaching);
+        $dependencyInjectionContainerCache = static::createCache('di');
 
         $bootState = new \stdClass;
         $bootState->done = false;
@@ -121,6 +124,7 @@ class Bootstrap
             ApplicationContext::class => Environment::getContext(),
             ConfigurationManager::class => $configurationManager,
             LogManager::class => $logManager,
+            'cache.di' => $dependencyInjectionContainerCache,
             'cache.core' => $coreCache,
             'cache.assets' => $assetsCache,
             PackageManager::class => $packageManager,
@@ -129,7 +133,7 @@ class Bootstrap
             'boot.state' => $bootState,
         ]);
 
-        $container = $builder->createDependencyInjectionContainer($packageManager, $coreCache, $failsafe);
+        $container = $builder->createDependencyInjectionContainer($packageManager, $dependencyInjectionContainerCache, $failsafe);
 
         // Push the container to GeneralUtility as we want to make sure its
         // makeInstance() method creates classes using the container from now on.
@@ -310,7 +314,11 @@ class Bootstrap
      */
     public static function createCache(string $identifier, bool $disableCaching = false): FrontendInterface
     {
-        $configuration = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$identifier] ?? [];
+        $cacheConfigurations = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'] ?? [];
+        $cacheConfigurations['di']['frontend'] = PhpFrontend::class;
+        $cacheConfigurations['di']['backend'] = ContainerBackend::class;
+        $cacheConfigurations['di']['options'] = [];
+        $configuration = $cacheConfigurations[$identifier] ?? [];
 
         $frontend = $configuration['frontend'] ?? VariableFrontend::class;
         $backend = $configuration['backend'] ?? Typo3DatabaseBackend::class;
diff --git a/typo3/sysext/core/Classes/DependencyInjection/Cache/ContainerBackend.php b/typo3/sysext/core/Classes/DependencyInjection/Cache/ContainerBackend.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e7176a98091dfde72d00120b443ff44fdd0f71c
--- /dev/null
+++ b/typo3/sysext/core/Classes/DependencyInjection/Cache/ContainerBackend.php
@@ -0,0 +1,36 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Core\DependencyInjection\Cache;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend;
+
+/**
+ * @internal
+ */
+class ContainerBackend extends SimpleFileBackend
+{
+    public function flush()
+    {
+        // disable cache flushing
+    }
+
+    public function set($entryIdentifier, $data, array $tags = [], $lifetime = null)
+    {
+        // Remove stale cache files, once a new DI container was built
+        parent::flush();
+        parent::set($entryIdentifier, $data, $tags, $lifetime);
+    }
+}
diff --git a/typo3/sysext/core/Classes/DependencyInjection/ContainerBuilder.php b/typo3/sysext/core/Classes/DependencyInjection/ContainerBuilder.php
index 9a60f4ade4cade9b4d138cd7a40bd970c3671858..2cabda533ab2e91fa92ca7501a466a386888fc15 100644
--- a/typo3/sysext/core/Classes/DependencyInjection/ContainerBuilder.php
+++ b/typo3/sysext/core/Classes/DependencyInjection/ContainerBuilder.php
@@ -22,6 +22,7 @@ use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
 use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
 use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
+use TYPO3\CMS\Core\Cache\Frontend\PhpFrontend;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Information\Typo3Version;
 use TYPO3\CMS\Core\Package\PackageManager;
@@ -62,6 +63,9 @@ class ContainerBuilder
      */
     public function createDependencyInjectionContainer(PackageManager $packageManager, FrontendInterface $cache, bool $failsafe = false): ContainerInterface
     {
+        if (!$cache instanceof PhpFrontend) {
+            throw new \RuntimeException('Cache must be instance of PhpFrontend', 1582022226);
+        }
         $serviceProviderRegistry = new ServiceProviderRegistry($packageManager, $failsafe);
 
         if ($failsafe) {
@@ -70,29 +74,16 @@ class ContainerBuilder
 
         $container = null;
 
-        $cacheIdentifier = $this->getCacheIdentifier();
+        $cacheIdentifier = $this->getCacheIdentifier($packageManager);
         $containerClassName = $cacheIdentifier;
 
         $hasCache = $cache->requireOnce($cacheIdentifier) !== false;
         if (!$hasCache) {
             $containerBuilder = $this->buildContainer($packageManager, $serviceProviderRegistry);
-            $code = $this->dumpContainer($containerBuilder, $cache);
-
-            // In theory we could use the $containerBuilder directly as $container,
-            // but as we patch the compiled source to use
-            // GeneralUtility::makeInstanceForDi, we need to use the compiled container.
-            // Once we remove support for singletons configured in ext_localconf.php
-            // and $GLOBALS['TYPO_CONF_VARS']['SYS']['Objects'], we can remove this,
-            // and use `$container = $containerBuilder` directly
-            $hasCache = $cache->requireOnce($cacheIdentifier) !== false;
-            if (!$hasCache) {
-                // $cacheIdentifier may be unavailable if the 'core' cache iis configured to
-                // use the NullBackend
-                eval($code);
-            }
+            $this->dumpContainer($containerBuilder, $cache, $cacheIdentifier);
+            $cache->requireOnce($cacheIdentifier);
         }
-        $fullyQualifiedContainerClassName = '\\' . $containerClassName;
-        $container = new $fullyQualifiedContainerClassName();
+        $container = new $containerClassName();
 
         foreach ($this->defaultServices as $id => $service) {
             $container->set('_early.' . $id, $service);
@@ -129,7 +120,7 @@ class ContainerBuilder
         // Store defaults entries in the DIC container
         // We need to use a workaround using aliases for synthetic services
         // But that's common in symfony (same technique is used to provide the
-        // symfony container interface as well.
+        // Symfony container interface as well).
         foreach (array_keys($this->defaultServices) as $id) {
             $syntheticId = '_early.' . $id;
             $containerBuilder->register($syntheticId)->setSynthetic(true)->setPublic(true);
@@ -144,11 +135,11 @@ class ContainerBuilder
     /**
      * @param SymfonyContainerBuilder $containerBuilder
      * @param FrontendInterface $cache
+     * @param string $cacheIdentifier
      * @return string
      */
-    protected function dumpContainer(SymfonyContainerBuilder $containerBuilder, FrontendInterface $cache): string
+    protected function dumpContainer(SymfonyContainerBuilder $containerBuilder, FrontendInterface $cache, string $cacheIdentifier): string
     {
-        $cacheIdentifier = $this->getCacheIdentifier();
         $containerClassName = $cacheIdentifier;
 
         $phpDumper = new PhpDumper($containerBuilder);
@@ -165,18 +156,20 @@ class ContainerBuilder
     }
 
     /**
+     * @param PackageManager $packageManager
      * @return string
      */
-    protected function getCacheIdentifier(): string
+    protected function getCacheIdentifier(PackageManager $packageManager): string
     {
-        return $this->cacheIdentifier ?? $this->createCacheIdentifier();
+        return $this->cacheIdentifier ?? $this->createCacheIdentifier($packageManager->getCacheIdentifier());
     }
 
     /**
+     * @param string|null $additionalIdentifier
      * @return string
      */
-    protected function createCacheIdentifier(): string
+    protected function createCacheIdentifier(string $additionalIdentifier = null): string
     {
-        return $this->cacheIdentifier = 'DependencyInjectionContainer_' . sha1((string)(new Typo3Version()) . Environment::getProjectPath() . 'DependencyInjectionContainer');
+        return $this->cacheIdentifier = 'DependencyInjectionContainer_' . sha1((string)(new Typo3Version()) . Environment::getProjectPath() . ($additionalIdentifier ?? '') . 'DependencyInjectionContainer');
     }
 }
diff --git a/typo3/sysext/core/Classes/Package/PackageManager.php b/typo3/sysext/core/Classes/Package/PackageManager.php
index 46c5b48e3990d74abc1a644057715fe5cbfb86fa..041767402b5ce6a4b1d7185c839bcadab1f6a5f3 100644
--- a/typo3/sysext/core/Classes/Package/PackageManager.php
+++ b/typo3/sysext/core/Classes/Package/PackageManager.php
@@ -139,9 +139,10 @@ class PackageManager implements SingletonInterface
     }
 
     /**
-     * @return string
+     * @internal
+     * @return string | null
      */
-    protected function getCacheIdentifier()
+    public function getCacheIdentifier()
     {
         if ($this->cacheIdentifier === null) {
             $mTime = @filemtime($this->packageStatesPathAndFilename);
diff --git a/typo3/sysext/core/Classes/ServiceProvider.php b/typo3/sysext/core/Classes/ServiceProvider.php
index 959b20feaa44dfbf1e5a37ffa8ea2a75471ed560..92878d73d17c6a05c33cf1886430bbd96ea59e58 100644
--- a/typo3/sysext/core/Classes/ServiceProvider.php
+++ b/typo3/sysext/core/Classes/ServiceProvider.php
@@ -65,10 +65,12 @@ class ServiceProvider extends AbstractServiceProvider
         $defaultCaches = [
             $container->get('cache.core'),
             $container->get('cache.assets'),
+            $container->get('cache.di'),
         ];
 
         $cacheManager = self::new($container, Cache\CacheManager::class, [$disableCaching]);
         $cacheManager->setCacheConfigurations($cacheConfigurations);
+        $cacheConfigurations['di']['groups'] = ['system'];
         foreach ($defaultCaches as $cache) {
             $cacheManager->registerCache($cache, $cacheConfigurations[$cache->getIdentifier()]['groups'] ?? ['all']);
         }
diff --git a/typo3/sysext/install/Classes/Service/ClearCacheService.php b/typo3/sysext/install/Classes/Service/ClearCacheService.php
index 175c11c96d9804f1811640ed1c2d185825a4053d..b7c5257a98094a9a69d4d64909ac9a2b78a202f2 100644
--- a/typo3/sysext/install/Classes/Service/ClearCacheService.php
+++ b/typo3/sysext/install/Classes/Service/ClearCacheService.php
@@ -14,7 +14,6 @@ namespace TYPO3\CMS\Install\Service;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -24,6 +23,10 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class ClearCacheService
 {
+    private const legacyDatabaseCacheTables = [
+        'cache_treelist',
+    ];
+
     /**
      * @var LateBootService
      */
@@ -49,41 +52,47 @@ class ClearCacheService
      */
     public function clearAll()
     {
-        // Delete typo3temp/Cache
-        GeneralUtility::flushDirectory(Environment::getVarPath() . '/cache', true, true);
-
-        // Get all table names from Default connection starting with 'cf_' and truncate them
+        // Low level flush of legacy database cache tables
         $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
-        $connection = $connectionPool->getConnectionByName('Default');
-        $tableNames = $connection->getSchemaManager()->listTableNames();
-        foreach ($tableNames as $tableName) {
-            if (strpos($tableName, 'cf_') === 0 || $tableName === 'cache_treelist') {
-                $connection->truncate($tableName);
-            }
+        foreach (self::legacyDatabaseCacheTables as $tableName) {
+            $connection = $connectionPool->getConnectionForTable($tableName);
+            $connection->truncate($tableName);
         }
 
-        // check tables on other connections
-        $remappedTables = isset($GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'])
-            ? array_keys((array)$GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'])
-            : [];
-        foreach ($remappedTables as $tableName) {
-            if (strpos((string)$tableName, 'cf_') === 0 || $tableName === 'cache_treelist') {
-                $connectionPool->getConnectionForTable($tableName)->truncate($tableName);
-            }
-        }
+        // Flush all caches defined in TYPO3_CONF_VARS, but not the ones defined by extensions in ext_localconf.php
+        $baseCaches = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'] ?? [];
+        $this->flushCaches($baseCaches);
+
+        // Remove DI container cache (this might be removed in preference of functionality to rebuild this cache)
+        // We need to remove using the remove method because the DI cache backend disables the flush method
+        $container = $this->lateBootService->getContainer();
+        $container->get('cache.di')->remove(get_class($container));
 
         // From this point on, the code may fatal, if some broken extension is loaded.
         $this->lateBootService->loadExtLocalconfDatabaseAndExtTables();
 
-        // The cache manager is already instantiated in the install tool
-        // (both in the failsafe and the late boot container), but
-        // with some hacked settings to disable caching of extbase and fluid.
-        // We want a "fresh" object here to operate on a different cache setup.
-        // cacheManager implements SingletonInterface, so the only way to get a "fresh"
-        // instance is by circumventing makeInstance and/or the objectManager and
-        // using new directly!
+        $extensionCaches = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'] ?? [];
+        // Loose comparison on purpose to allow changed ordering of the array
+        if ($baseCaches != $extensionCaches) {
+            // When configuration has changed during loading of extensions (due to ext_localconf.php), flush all caches again
+            $this->flushCaches($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
+        }
+    }
+
+    /**
+     * The cache manager is already instantiated in the install tool
+     * (both in the failsafe and the late boot container), but
+     * with settings to disable caching (all caches using NullBackend).
+     * We want a "fresh" object here to operate with the really configured cache backends.
+     * CacheManager implements SingletonInterface, so the only way to get a "fresh"
+     * instance is by circumventing makeInstance and using new directly!
+     *
+     * @param array $cacheConfiguration
+     */
+    private function flushCaches(array $cacheConfiguration): void
+    {
         $cacheManager = new \TYPO3\CMS\Core\Cache\CacheManager();
-        $cacheManager->setCacheConfigurations($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']);
+        $cacheManager->setCacheConfigurations($cacheConfiguration);
         $cacheManager->flushCaches();
     }
 }
diff --git a/typo3/sysext/install/Classes/Service/LateBootService.php b/typo3/sysext/install/Classes/Service/LateBootService.php
index 291d486eafac4dfddbd79bbb2a7133885e112bfb..d3486017a03aca9b572e1381276db497c12d87ef 100644
--- a/typo3/sysext/install/Classes/Service/LateBootService.php
+++ b/typo3/sysext/install/Classes/Service/LateBootService.php
@@ -69,15 +69,12 @@ class LateBootService
     private function prepareContainer(): ContainerInterface
     {
         $packageManager = $this->failsafeContainer->get(PackageManager::class);
-
-        // Use caching for the full boot – uncached symfony autowiring for every install-tool lateboot request would be too slow.
-        $disableCaching = false;
-        $coreCache = Bootstrap::createCache('core', $disableCaching);
+        $dependencyInjectionContainerCache = $this->failsafeContainer->get('cache.di');
 
         $failsafe = false;
 
         // Build a non-failsafe container which is required for loading ext_localconf
-        return $this->container = $this->containerBuilder->createDependencyInjectionContainer($packageManager, $coreCache, $failsafe);
+        return $this->container = $this->containerBuilder->createDependencyInjectionContainer($packageManager, $dependencyInjectionContainerCache, $failsafe);
     }
 
     /**