diff --git a/core/core.services.yml b/core/core.services.yml
index 98ddc9e..6ae0916 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -299,7 +299,7 @@ services:
     arguments: ['@entity.manager', '@string_translation']
   theme_handler:
     class: Drupal\Core\Extension\ThemeHandler
-    arguments: ['@app.root', '@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@config.manager', '@router.builder_indicator']
+    arguments: ['@app.root', '@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@config.manager', '@router.builder']
   entity.manager:
     class: Drupal\Core\Entity\EntityManager
     arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', '@language_manager', '@string_translation', '@class_resolver', '@typed_data_manager', '@entity.definitions.installed', '@event_dispatcher']
@@ -553,7 +553,7 @@ services:
     arguments: ['@state']
   router.builder:
     class: Drupal\Core\Routing\RouteBuilder
-    arguments: ['@router.dumper', '@lock', '@event_dispatcher', '@module_handler', '@controller_resolver', '@access_manager.check_provider', '@router.builder_indicator']
+    arguments: ['@router.dumper', '@lock', '@event_dispatcher', '@module_handler', '@controller_resolver', '@access_manager.check_provider', '@cache.default']
   router.rebuild_subscriber:
     class: Drupal\Core\EventSubscriber\RouterRebuildSubscriber
     arguments: ['@router.builder']
diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
index c6f3921..a15799c 100644
--- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php
+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
@@ -201,7 +201,6 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
 
         // Clear plugin manager caches and flag router to rebuild if requested.
         \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();
-        \Drupal::service('router.builder_indicator')->setRebuildNeeded();
 
         // Set the schema version to the number of the last update provided by
         // the module, or the minimum core schema version.
@@ -275,6 +274,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
 
     // If any modules were newly installed, invoke hook_modules_installed().
     if (!empty($modules_installed)) {
+      \Drupal::service('router.builder')->rebuild();
       $this->moduleHandler->invokeAll('modules_installed', array($modules_installed));
     }
 
@@ -356,6 +356,9 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
         }
       }
 
+      // @todo: make this a method on the RouteBuilder.
+      \Drupal::service('cache.default')->delete('routebuilder:yml:' . $module);
+
       // Allow modules to react prior to the uninstallation of a module.
       $this->moduleHandler->invokeAll('module_preuninstall', array($module));
 
@@ -400,7 +403,6 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
 
       // Clear plugin manager caches and flag router to rebuild if requested.
       \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions();
-      \Drupal::service('router.builder_indicator')->setRebuildNeeded();
 
       // Update the kernel to exclude the uninstalled modules.
       $this->updateKernel($module_filenames);
@@ -419,6 +421,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
       $schema_store = \Drupal::keyValue('system.schema');
       $schema_store->delete($module);
     }
+    \Drupal::service('router.builder')->rebuild();
     drupal_get_installed_schema_version(NULL, TRUE);
 
     // Let other modules react.
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php
index 8beb184..8442ccf 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandler.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php
@@ -13,7 +13,7 @@
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Config\ConfigInstallerInterface;
 use Drupal\Core\Config\ConfigManagerInterface;
-use Drupal\Core\Routing\RouteBuilderIndicatorInterface;
+use Drupal\Core\Routing\RouteBuilderInterface;
 use Drupal\Core\State\StateInterface;
 use Psr\Log\LoggerInterface;
 
@@ -87,11 +87,11 @@ class ThemeHandler implements ThemeHandlerInterface {
   protected $logger;
 
   /**
-   * The route builder indicator to rebuild the routes if a theme is installed.
+   * The route builder to rebuild the routes if a theme is installed.
    *
-   * @var \Drupal\Core\Routing\RouteBuilderIndicatorInterface
+   * @var \Drupal\Core\Routing\RouteBuilderInterface
    */
-  protected $routeBuilderIndicator;
+  protected $routeBuilder;
 
   /**
    * An extension discovery instance.
@@ -144,13 +144,13 @@ class ThemeHandler implements ThemeHandlerInterface {
    *   database.
    * @param \Drupal\Core\Config\ConfigManagerInterface $config_manager
    *   The config manager used to uninstall a theme.
-   * @param \Drupal\Core\Routing\RouteBuilderIndicatorInterface $route_builder_indicator
-   *   (optional) The route builder indicator service to rebuild the routes if a
+   * @param \Drupal\Core\Routing\RouteBuilderInterface $route_builder
+   *   (optional) The route builder service to rebuild the routes if a
    *   theme is installed.
    * @param \Drupal\Core\Extension\ExtensionDiscovery $extension_discovery
    *   (optional) A extension discovery instance (for unit tests).
    */
-  public function __construct($root, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, StateInterface $state, InfoParserInterface $info_parser,LoggerInterface $logger, AssetCollectionOptimizerInterface $css_collection_optimizer = NULL, ConfigInstallerInterface $config_installer = NULL, ConfigManagerInterface $config_manager = NULL, RouteBuilderIndicatorInterface $route_builder_indicator = NULL, ExtensionDiscovery $extension_discovery = NULL) {
+  public function __construct($root, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, StateInterface $state, InfoParserInterface $info_parser,LoggerInterface $logger, AssetCollectionOptimizerInterface $css_collection_optimizer = NULL, ConfigInstallerInterface $config_installer = NULL, ConfigManagerInterface $config_manager = NULL, RouteBuilderInterface $route_builder = NULL, ExtensionDiscovery $extension_discovery = NULL) {
     $this->root = $root;
     $this->configFactory = $config_factory;
     $this->moduleHandler = $module_handler;
@@ -160,7 +160,7 @@ public function __construct($root, ConfigFactoryInterface $config_factory, Modul
     $this->cssCollectionOptimizer = $css_collection_optimizer;
     $this->configInstaller = $config_installer;
     $this->configManager = $config_manager;
-    $this->routeBuilderIndicator = $route_builder_indicator;
+    $this->routeBuilder = $route_builder;
     $this->extensionDiscovery = $extension_discovery;
   }
 
@@ -614,8 +614,8 @@ protected function getExtensionDiscovery() {
    * Resets some other systems like rebuilding the route information or caches.
    */
   protected function resetSystem() {
-    if ($this->routeBuilderIndicator) {
-      $this->routeBuilderIndicator->setRebuildNeeded();
+    if ($this->routeBuilder) {
+      $this->routeBuilder->rebuild();
     }
     $this->systemListReset();
 
diff --git a/core/lib/Drupal/Core/Routing/RouteBuilder.php b/core/lib/Drupal/Core/Routing/RouteBuilder.php
index a4b17e2..dfea546 100644
--- a/core/lib/Drupal/Core/Routing/RouteBuilder.php
+++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Routing;
 
 use Drupal\Component\Discovery\YamlDiscovery;
+use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Access\CheckProviderInterface;
 use Drupal\Core\Controller\ControllerResolverInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
@@ -58,13 +59,6 @@ class RouteBuilder implements RouteBuilderInterface {
   protected $moduleHandler;
 
   /**
-   * The route builder indicator.
-   *
-   * @var \Drupal\Core\Routing\RouteBuilderIndicatorInterface
-   */
-  protected $routeBuilderIndicator;
-
-  /**
    * The controller resolver.
    *
    * @var \Drupal\Core\Controller\ControllerResolverInterface
@@ -107,17 +101,17 @@ class RouteBuilder implements RouteBuilderInterface {
    *   The controller resolver.
    * @param \Drupal\Core\Access\CheckProviderInterface $check_provider
    *   The check provider.
-   * @param \Drupal\Core\Routing\RouteBuilderIndicatorInterface $route_build_indicator
-   *   The route build indicator.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
+   *   The cache object.
    */
-  public function __construct(MatcherDumperInterface $dumper, LockBackendInterface $lock, EventDispatcherInterface $dispatcher, ModuleHandlerInterface $module_handler, ControllerResolverInterface $controller_resolver, CheckProviderInterface $check_provider, RouteBuilderIndicatorInterface $route_build_indicator = NULL) {
+  public function __construct(MatcherDumperInterface $dumper, LockBackendInterface $lock, EventDispatcherInterface $dispatcher, ModuleHandlerInterface $module_handler, ControllerResolverInterface $controller_resolver, CheckProviderInterface $check_provider, CacheBackendInterface $cache) {
     $this->dumper = $dumper;
     $this->lock = $lock;
     $this->dispatcher = $dispatcher;
     $this->moduleHandler = $module_handler;
     $this->controllerResolver = $controller_resolver;
-    $this->routeBuilderIndicator = $route_build_indicator;
     $this->checkProvider = $check_provider;
+    $this->cache = $cache;
   }
 
   /**
@@ -176,7 +170,6 @@ public function rebuild() {
         $route = new Route($route_info['path'], $route_info['defaults'], $route_info['requirements'], $route_info['options']);
         $collection->add($name, $route);
       }
-
     }
 
     // DYNAMIC is supposed to be used to add new routes based upon all the
@@ -193,7 +186,6 @@ public function rebuild() {
     $this->dumper->addRoutes($collection);
     $this->dumper->dump();
 
-    $this->routeBuilderIndicator->setRebuildDone();
     $this->lock->release('router_rebuild');
     $this->dispatcher->dispatch(RoutingEvents::FINISHED, new Event());
     $this->building = FALSE;
@@ -206,25 +198,20 @@ public function rebuild() {
   /**
    * {@inheritdoc}
    */
-  public function getCollectionDuringRebuild() {
-    return $this->routeCollection ?: FALSE;
+  public function setRebuildNeeded() {
   }
 
   /**
    * {@inheritdoc}
    */
   public function rebuildIfNeeded() {
-    if ($this->routeBuilderIndicator->isRebuildNeeded()) {
-      return $this->rebuild();
-    }
-    return FALSE;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function setRebuildNeeded() {
-    $this->routeBuilderIndicator->setRebuildNeeded();
+  public function getCollectionDuringRebuild() {
+    return $this->routeCollection ?: FALSE;
   }
 
   /**
@@ -234,10 +221,37 @@ public function setRebuildNeeded() {
    *   The defined routes, keyed by provider.
    */
   protected function getRouteDefinitions() {
-    if (!isset($this->yamlDiscovery)) {
-      $this->yamlDiscovery = new YamlDiscovery('routing', $this->moduleHandler->getModuleDirectories());
+    $route_definitions = [];
+    $cache_ids = [];
+    $module_cache_id_map = [];
+
+    $module_dirs = $this->moduleHandler->getModuleDirectories();
+    foreach ($module_dirs as $module => $dir) {
+      $cache_ids[] = 'routebuilder:yml:' . $module;
+      $module_cache_id_map['routebuilder:yml:' . $module] = $module;
+    }
+    foreach ($this->cache->getMultiple($cache_ids) as $cache) {
+      if ($cache->data) {
+        $route_definitions[$module_cache_id_map[$cache->cid]] = $cache->data;
+      }
+      unset($module_dirs[$module_cache_id_map[$cache->cid]]);
+    }
+    if ($module_dirs) {
+      if (!isset($this->yamlDiscovery)) {
+        $this->yamlDiscovery = new YamlDiscovery('routing', $module_dirs);
+      }
+      foreach ($this->yamlDiscovery->findAll() as $module => $routes) {
+        $route_definitions[$module] = $routes;
+        $this->cache->set('routebuilder:yml:' . $module, $routes);
+        unset($module_dirs[$module]);
+      }
+      // Cache the fact that this module has no routing yml to parse.
+      foreach ($module_dirs as $module) {
+        $routes = [];
+        $this->cache->set('routebuilder:yml:' . $module, $routes);
+      }
     }
-    return $this->yamlDiscovery->findAll();
+    return $route_definitions;
   }
 
 }
