diff --git includes/bootstrap.inc includes/bootstrap.inc
index 0739332..4011a45 100644
--- includes/bootstrap.inc
+++ includes/bootstrap.inc
@@ -732,25 +732,14 @@ function drupal_get_filename($type, $name, $filename = NULL) {
 function variable_initialize($conf = array()) {
   // NOTE: caching the variables improves performance by 20% when serving
   // cached pages.
-  if ($cached = cache_get('variables', 'cache_bootstrap')) {
-    $variables = $cached->data;
+  $cache = &drupal_static('variable');
+  if ($cached = cache_get('variable_cache', 'cache_bootstrap')) {
+    $cache = $cached->data;
   }
   else {
-    // Cache miss. Avoid a stampede.
-    $name = 'variable_init';
-    if (!lock_acquire($name, 1)) {
-      // Another request is building the variable cache.
-      // Wait, then re-run this function.
-      lock_wait($name);
-      return variable_initialize($conf);
-    }
-    else {
-      // Proceed with variable rebuild.
-      $variables = array_map('unserialize', db_query('SELECT name, value FROM {variable}')->fetchAllKeyed());
-      cache_set('variables', $variables, 'cache_bootstrap');
-      lock_release($name);
-    }
+    $cache = array('variables' => array(), 'defaults' => array());
   }
+  $variables = $cache['variables'];
 
   foreach ($conf as $name => $value) {
     $variables[$name] = $value;
@@ -779,11 +768,65 @@ function variable_initialize($conf = array()) {
  */
 function variable_get($name, $default = NULL) {
   global $conf;
+  if (isset($conf[$name])) {
+    return $conf[$name];
+  }
+  // Use the advanced drupal_static() pattern, since this is called very often.
+  static $drupal_static_fast;
+  if (!isset($drupal_static_fast)) {
+    $drupal_static_fast['cache'] = &drupal_static('variable');
+  }
+  $cache = &$drupal_static_fast['cache'];
+
+  // $cache is populated in variable_initialize() for each request. If it's not
+  // available here we are in a lower bootstrap phase where the database and
+  // cache system may not be available yet.
+  if (isset($cache)) {
+    // First check the cached list of variables that should use defaults.
+    if (isset($cache['defaults'][$name])) {
+      return $default;
+    }
+    // If the variable is neither in $conf, nor in $cache['defaults'] then
+    // query the database.
+    else {
+      // Check if variables are cacheable for this request, if so record the
+      // current size of the variable cache and set a flag to write the cache
+      // later.
+      if (!isset($cache['write_cache'])) {
+        $cache['write_cache'] = array(
+          'variables_count' => count($cache['variables']),
+          'defaults_count' => count($cache['defaults']),
+        );
+      }
+      $value = variable_get_from_storage($name);
+      if (isset($value)) {
+        $conf[$name] = $cache['variables'][$name] = $value;
+      }
+      else {
+        $cache['defaults'][$name] = 1;
+      }
+    }
+  }
 
   return isset($conf[$name]) ? $conf[$name] : $default;
 }
 
 /**
+ * Fetch a variable directly from storage, bypassing any values set in $conf.
+ * @param $name
+ *   The name of the variable.
+ *
+ * @return
+ *   The value of the variable, or FALSE if it is not stored in the database.
+ */
+function variable_get_from_storage($name) {
+  $result = db_query('SELECT value FROM {variable} WHERE name = :name', array(':name' => $name))->fetchField();
+  if ($result) {
+    return unserialize($result);
+  }
+}
+
+/**
  * Sets a persistent variable.
  *
  * Case-sensitivity of the variable_* functions depends on the database
@@ -803,8 +846,11 @@ function variable_set($name, $value) {
   global $conf;
 
   db_merge('variable')->key(array('name' => $name))->fields(array('value' => serialize($value)))->execute();
-
-  cache_clear_all('variables', 'cache_bootstrap');
+  // Set the variable cache to empty arrays, this ensures that requests trying
+  // set the cache immediately after the variable is written will not do so
+  // with a stale cache.
+  cache_set('variable_cache', array('variables' => array(), 'defaults' => array()), 'cache_bootstrap');
+  cache_clear_all('variable_cache:', 'cache', TRUE);
 
   $conf[$name] = $value;
 }
@@ -828,7 +874,10 @@ function variable_del($name) {
   db_delete('variable')
     ->condition('name', $name)
     ->execute();
-  cache_clear_all('variables', 'cache_bootstrap');
+  // Set the cache to empty arrays, this ensures that requests setting the
+  // cache immediately after this will not do so with stale cache entries.
+  cache_set('variable_cache', array('variables' => array(), 'defaults' => array()), 'cache_bootstrap');
+  cache_clear_all('variable_cache:', 'cache', TRUE);
 
   unset($conf[$name]);
 }
@@ -2125,10 +2174,6 @@ function _drupal_bootstrap_database() {
 function _drupal_bootstrap_variables() {
   global $conf;
 
-  // Initialize the lock system.
-  require_once DRUPAL_ROOT . '/' . variable_get('lock_inc', 'includes/lock.inc');
-  lock_initialize();
-
   // Load variables from the database, but do not overwrite variables set in settings.php.
   $conf = variable_initialize(isset($conf) ? $conf : array());
   // Load bootstrap modules.
@@ -2142,6 +2187,10 @@ function _drupal_bootstrap_variables() {
 function _drupal_bootstrap_page_header() {
   bootstrap_invoke_all('boot');
 
+  // Prepare for non-cached page workflow.
+  require_once DRUPAL_ROOT . '/' . variable_get('lock_inc', 'includes/lock.inc');
+  lock_initialize();
+
   if (!drupal_is_cli()) {
     ob_start();
     drupal_page_header();
diff --git includes/common.inc includes/common.inc
index 62a5037..d6bdbcf 100644
--- includes/common.inc
+++ includes/common.inc
@@ -2562,6 +2562,7 @@ function drupal_page_footer() {
   }
 
   _registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE);
+  variable_write_cache('variable_cache:' . strtok(current_path(), '/'), 'cache');
   drupal_cache_system_paths();
   module_implements_write_cache();
   system_run_automated_cron();
@@ -2590,6 +2591,77 @@ function drupal_exit($destination = NULL) {
 }
 
 /**
+ * Initialize the variables cache after full bootstrap.
+ */
+function variable_initialize_full() {
+  // Allow variables fetched up to this point to be cached in the global
+  // variable_bootstrap cache.
+  variable_write_cache('variable_cache', 'cache_bootstrap');
+
+  // After full bootstrap, we segment the variables cache by system path root.
+  // For example 'node' or 'admin'.
+  $path = strtok(current_path(), '/');
+
+  $cache = &drupal_static('variable');
+  if ($cached = cache_get("variable_cache:$path", 'cache')) {
+    $cache = $cached->data;
+  }
+  else {
+    $cache = array('variables' => array(), 'defaults' => array());
+  }
+  $variables = $cache['variables'];
+
+  // Ensure existing variables in $conf override cached values.
+  foreach ($GLOBALS['conf'] as $name => $value) {
+    $variables[$name] = $value;
+  }
+  $GLOBALS['conf'] = $variables;
+}
+
+/**
+ * Update the variable cache after a cache miss.
+ */
+function variable_write_cache($cid, $bin) {
+  $cache = &drupal_static('variable');
+  if (!empty($cache['write_cache'])) {
+    // Get a fresh copy of the variable cache from cache_get(), this will
+    // include any changes made by other requests between variable_initialize()
+    // and variable_write_cache().
+    if ($cached = cache_get($cid, $bin)) {
+      $current_cache = $cached->data;
+
+      // Compare the current cache sizes to those requested during
+      // variable_initialize(), if the current size is smaller, another
+      // request must have reset the cache in between.
+      if (count($current_cache['variables']) < $cache['write_cache']['variables_count'] || count($current_cache['defaults']) < $cache['write_cache']['defaults_count']) {
+        // Return early since there's nothing to do here.
+        return FALSE;
+      }
+      else {
+        // Merge the variables built during this request with the latest
+        // version of the cache, this ensures that this request will not
+        // undo caching of variables by another process. Compare the size of
+        // the cache before and after this process to avoid trying to set
+        // cache entries redundantly.
+        $count = count($cache['variables']) + count($cache['defaults']);
+
+        $cache = array_merge($current_cache, $cache);
+        // If the size of the data to be cached has not increased, there is no
+        // point writing to the cache again.
+        if ($count && $count < count($cache['variables']) + count($cache['defaults'])) {
+          return FALSE;
+        }
+      }
+    }
+    // If the cache is empty, or if it has not changed since the beginning of
+    // the request, write the new cache entry.
+    unset($cache['write_cache']);
+    cache_set($cid, $cache, $bin);
+  }
+  drupal_static_reset('variable');
+}
+
+/**
  * Form an associative array from a linear array.
  *
  * This function walks through the provided array and constructs an associative
@@ -4928,6 +5000,7 @@ function _drupal_bootstrap_full() {
     menu_set_custom_theme();
     drupal_theme_initialize();
     module_invoke_all('init');
+    variable_initialize_full();
   }
 }
 
diff --git modules/simpletest/drupal_web_test_case.php modules/simpletest/drupal_web_test_case.php
index 17cbb1f..c0b5102 100644
--- modules/simpletest/drupal_web_test_case.php
+++ modules/simpletest/drupal_web_test_case.php
@@ -1239,16 +1239,6 @@ class DrupalWebTestCase extends DrupalTestCase {
       ->condition('test_id', $this->testId)
       ->execute();
 
-    // Clone the current connection and replace the current prefix.
-    $connection_info = Database::getConnectionInfo('default');
-    Database::renameConnection('default', 'simpletest_original_default');
-    foreach ($connection_info as $target => $value) {
-      $connection_info[$target]['prefix'] = array(
-        'default' => $value['prefix']['default'] . $this->databasePrefix,
-      );
-    }
-    Database::addConnectionInfo('default', 'default', $connection_info['default']);
-
     // Store necessary current values before switching to prefixed database.
     $this->originalLanguage = $language;
     $this->originalLanguageDefault = variable_get('language_default');
@@ -1277,6 +1267,16 @@ class DrupalWebTestCase extends DrupalTestCase {
     file_prepare_directory($temp_files_directory, FILE_CREATE_DIRECTORY);
     $this->generatedTestFiles = FALSE;
 
+    // Clone the current connection and replace the current prefix.
+    $connection_info = Database::getConnectionInfo('default');
+    Database::renameConnection('default', 'simpletest_original_default');
+    foreach ($connection_info as $target => $value) {
+      $connection_info[$target]['prefix'] = array(
+        'default' => $value['prefix']['default'] . $this->databasePrefix,
+      );
+    }
+    Database::addConnectionInfo('default', 'default', $connection_info['default']);
+
     // Log fatal errors.
     ini_set('log_errors', 1);
     ini_set('error_log', $public_files_directory . '/error.log');
@@ -1430,7 +1430,9 @@ class DrupalWebTestCase extends DrupalTestCase {
    */
   protected function refreshVariables() {
     global $conf;
-    cache_clear_all('variables', 'cache_bootstrap');
+    cache_clear_all('variable_cache', 'cache_bootstrap');
+    cache_clear_all('variable_cache:', 'cache', TRUE);
+    drupal_static_reset('variable');
     $conf = variable_initialize();
   }
 
diff --git modules/simpletest/tests/upgrade/upgrade.test modules/simpletest/tests/upgrade/upgrade.test
index 263baff..c9d07d0 100644
--- modules/simpletest/tests/upgrade/upgrade.test
+++ modules/simpletest/tests/upgrade/upgrade.test
@@ -34,6 +34,13 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase {
   protected function setUp() {
     global $user, $language, $conf;
 
+    // Store necessary current values before switching to prefixed database.
+    $this->originalLanguage = $language;
+    $this->originalLanguageDefault = variable_get('language_default');
+    $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
+    $this->originalProfile = drupal_get_profile();
+    $clean_url_original = variable_get('clean_url', 0);
+
     // Load the Update API.
     require_once DRUPAL_ROOT . '/includes/update.inc';
 
@@ -60,13 +67,6 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase {
     }
     Database::addConnectionInfo('default', 'default', $connection_info['default']);
 
-    // Store necessary current values before switching to prefixed database.
-    $this->originalLanguage = $language;
-    $this->originalLanguageDefault = variable_get('language_default');
-    $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
-    $this->originalProfile = drupal_get_profile();
-    $clean_url_original = variable_get('clean_url', 0);
-
     // Unregister the registry.
     // This is required to make sure that the database layer works properly.
     spl_autoload_unregister('drupal_autoload_class');
