diff --git a/core/includes/common.inc b/core/includes/common.inc
index 4c86953..21aecda 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -3032,7 +3032,7 @@ function drupal_pre_render_styles($elements) {
   // browser-caching. The string changes on every update or full cache
   // flush, forcing browsers to load a new copy of the files, as the
   // URL changed.
-  $query_string = variable_get('css_js_query_string', '0');
+  $query_string = state()->get('system.css_js_query_string') ?: '0';
 
   // For inline CSS to validate as XHTML, all CSS containing XHTML needs to be
   // wrapped in CDATA. To make that backwards compatible with HTML 4, we need to
@@ -4027,7 +4027,7 @@ function drupal_pre_render_scripts($elements) {
   // URL changed. Files that should not be cached (see drupal_add_js())
   // get REQUEST_TIME as query-string instead, to enforce reload on every
   // page request.
-  $default_query_string = variable_get('css_js_query_string', '0');
+  $default_query_string = state()->get('system.css_js_query_string') ?: '0';
 
   // For inline JavaScript to validate as XHTML, all JavaScript containing
   // XHTML needs to be wrapped in CDATA. To make that backwards compatible
@@ -6906,7 +6906,7 @@ function drupal_flush_all_caches() {
  */
 function _drupal_flush_css_js() {
   // The timestamp is converted to base 36 in order to make it more compact.
-  variable_set('css_js_query_string', base_convert(REQUEST_TIME, 10, 36));
+  state()->set('system.css_js_query_string', base_convert(REQUEST_TIME, 10, 36));
 }
 
 /**
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 3968682..e0fab7e 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -289,8 +289,13 @@ function install_begin_request(&$install_state) {
   // Determine whether the configuration system is ready to operate.
   $install_state['config_verified'] = install_verify_config_directory(CONFIG_ACTIVE_DIRECTORY) && install_verify_config_directory(CONFIG_STAGING_DIRECTORY);
 
-  // If it is not, replace the configuration storage with the InstallStorage
-  // implementation, for the following reasons:
+  // Check existing settings.php.
+  $install_state['database_verified'] = install_verify_database_settings();
+  $install_state['settings_verified'] = $install_state['config_verified'] && $install_state['database_verified'];
+
+  // If config or database it is not available, replace the storage engines with
+  // implementations that do not depend on the database, for the following
+  // reasons:
   // - The first call into drupal_container() will try to set up the regular
   //   runtime configuration storage, using the CachedStorage by default. It
   //   calls config_get_config_directory() to retrieve the config directory to
@@ -312,7 +317,7 @@ function install_begin_request(&$install_state) {
   // This override is reverted as soon as the config directory has been set up
   // successfully.
   // @see drupal_install_config_directories()
-  if (!$install_state['config_verified']) {
+  if (!$install_state['config_verified'] || !$install_state['database_verified']) {
     // @todo Move into a proper Drupal\Core\DependencyInjection\InstallContainerBuilder.
     $container = new ContainerBuilder();
 
@@ -322,6 +327,12 @@ function install_begin_request(&$install_state) {
     $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory')
       ->addArgument(new Reference('config.storage'))
       ->addArgument(new Reference('dispatcher'));
+    $container->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueFactory')
+      ->addArgument(new Reference('service_container'));
+    $container->register('keyvalue.memory', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory');
+    // Override the default keyvalue storage to use memory as the database is
+    // not available.
+    $conf['keyvalue_default'] = 'keyvalue.memory';
     drupal_container($container);
   }
 
@@ -364,10 +375,6 @@ function install_begin_request(&$install_state) {
   // accessing the database before it is set up yet.)
   drupal_maintenance_theme();
 
-  // Check existing settings.php.
-  $install_state['database_verified'] = install_verify_database_settings();
-  $install_state['settings_verified'] = $install_state['config_verified'] && $install_state['database_verified'];
-
   if ($install_state['database_verified']) {
     // Initialize the database system. Note that the connection
     // won't be initialized until it is actually requested.
@@ -1082,7 +1089,7 @@ function install_database_errors($database, $settings_file) {
  * @see install_settings_form_validate()
  */
 function install_settings_form_submit($form, &$form_state) {
-  global $install_state;
+  global $install_state, $conf;
 
   // Update global settings array and save.
   $settings['databases'] = array(
@@ -1099,6 +1106,10 @@ function install_settings_form_submit($form, &$form_state) {
   // Add the config directories to settings.php.
   drupal_install_config_directories();
 
+  // The container is about to be rebuilt so we need to unset the keyvalue
+  // storage override that the installer is using.
+  unset($conf['keyvalue_default']);
+
   // We have valid configuration directories in settings.php.
   // Reset the service container, so the config.storage service will use the
   // actual active storage for installing configuration.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php
index 9009bbb..2589108 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/CascadingStylesheetsTest.php
@@ -98,7 +98,7 @@ function testRenderFile() {
     $styles = drupal_get_css();
     $this->assertTrue(strpos($styles, $css) > 0, 'Rendered CSS includes the added stylesheet.');
     // Verify that newlines are properly added inside style tags.
-    $query_string = variable_get('css_js_query_string', '0');
+    $query_string = state()->get('system.css_js_query_string') ?: '0';
     $css_processed = "<style media=\"all\">\n@import url(\"" . check_plain(file_create_url($css)) . "?" . $query_string ."\");\n</style>";
     $this->assertEqual(trim($styles), $css_processed, 'Rendered CSS includes newlines inside style tags for JavaScript use.');
   }
@@ -248,7 +248,7 @@ function testAlter() {
    */
   function testAddCssFileWithQueryString() {
     $this->drupalGet('common-test/query-string');
-    $query_string = variable_get('css_js_query_string', '0');
+    $query_string = state()->get('system.css_js_query_string') ?: '0';
     $this->assertRaw(drupal_get_path('module', 'node') . '/node.admin.css?' . $query_string, 'Query string was appended correctly to css.');
     $this->assertRaw(drupal_get_path('module', 'node') . '/node-fake.css?arg1=value1&amp;arg2=value2', 'Query string not escaped on a URI.');
   }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
index 4c4198c..446c0db 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
@@ -100,7 +100,7 @@ function testAddExternal() {
    * Tests adding external JavaScript Files with the async attribute.
    */
   function testAsyncAttribute() {
-    $default_query_string = variable_get('css_js_query_string', '0');
+    $default_query_string = state()->get('system.css_js_query_string') ?: '0';
 
     drupal_add_library('system', 'drupal');
     drupal_add_js('http://example.com/script.js', array('async' => TRUE));
@@ -118,7 +118,7 @@ function testAsyncAttribute() {
    * Tests adding external JavaScript Files with the defer attribute.
    */
   function testDeferAttribute() {
-    $default_query_string = variable_get('css_js_query_string', '0');
+    $default_query_string = state()->get('system.css_js_query_string') ?: '0';
 
     drupal_add_library('system', 'drupal');
     drupal_add_js('http://example.com/script.js', array('defer' => TRUE));
@@ -255,7 +255,7 @@ function testDifferentWeight() {
    * @see drupal_pre_render_conditional_comments()
    */
   function testBrowserConditionalComments() {
-    $default_query_string = variable_get('css_js_query_string', '0');
+    $default_query_string = state()->get('system.css_js_query_string') ?: '0';
 
     drupal_add_library('system', 'drupal');
     drupal_add_js('core/misc/collapse.js', array('browsers' => array('IE' => 'lte IE 8', '!IE' => FALSE)));
@@ -284,7 +284,7 @@ function testVersionQueryString() {
    * Tests JavaScript grouping and aggregation.
    */
   function testAggregation() {
-    $default_query_string = variable_get('css_js_query_string', '0');
+    $default_query_string = state()->get('system.css_js_query_string') ?: '0';
 
     // To optimize aggregation, items with the 'every_page' option are ordered
     // ahead of ones without. The order of JavaScript execution must be the
@@ -527,7 +527,7 @@ function testGetLibrary() {
    */
   function testAddJsFileWithQueryString() {
     $this->drupalGet('common-test/query-string');
-    $query_string = variable_get('css_js_query_string', '0');
+    $query_string = state()->get('system.css_js_query_string') ?: '0';
     $this->assertRaw(drupal_get_path('module', 'node') . '/node.js?' . $query_string, 'Query string was appended correctly to js.');
   }
 }
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 1f191ac..b8d1a95 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -2194,12 +2194,13 @@ function system_update_8031() {
 }
 
 /**
- * Removes the drupal_js_cache_files variable.
+ * Removes the drupal_js_cache_files and css_js_query_string variables.
  *
  * @ingroup config_upgrade
  */
 function system_update_8032() {
   update_variable_del('drupal_js_cache_files');
+  update_variable_del('css_js_query_string');
 }
 
 /**
