diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
index 9416548..dcfa8ab 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
@@ -53,9 +53,6 @@ class DatabaseBackend implements CacheBackendInterface {
    */
   function getMultiple(&$cids) {
     try {
-      // Garbage collection necessary when enforcing a minimum cache lifetime.
-      $this->garbageCollection($this->bin);
-
       // When serving cached pages, the overhead of using db_select() was found
       // to add around 30% overhead to the request. Since $this->bin is a
       // variable, this means the call to db_query() here uses a concatenated
@@ -95,8 +92,6 @@ class DatabaseBackend implements CacheBackendInterface {
    *   valid item to load.
    */
   protected function prepareItem($cache) {
-    global $user;
-
     if (!isset($cache->data)) {
       return FALSE;
     }
@@ -199,29 +194,23 @@ class DatabaseBackend implements CacheBackendInterface {
    * Implements Drupal\Core\Cache\CacheBackendInterface::expire().
    */
   function expire() {
-    if (variable_get('cache_lifetime', 0)) {
-      // We store the time in the current user's session. We then simulate
-      // that the cache was flushed for this user by not returning cached
-      // data that was cached before the timestamp.
-      $_SESSION['cache_expiration'][$this->bin] = REQUEST_TIME;
-
-      $cache_flush = variable_get('cache_flush_' . $this->bin, 0);
-      if ($cache_flush == 0) {
-        // This is the first request to clear the cache, start a timer.
-        variable_set('cache_flush_' . $this->bin, REQUEST_TIME);
-      }
-      elseif (REQUEST_TIME > ($cache_flush + variable_get('cache_lifetime', 0))) {
-        // Clear the cache for everyone; cache_lifetime seconds have passed
-        // since the first request to clear the cache.
-        db_delete($this->bin)
-          ->condition('expire', CACHE_PERMANENT, '<>')
-          ->condition('expire', REQUEST_TIME, '<')
-          ->execute();
-        variable_set('cache_flush_' . $this->bin, 0);
-      }
-    }
-    else {
-      // No minimum cache lifetime, flush all temporary cache entries now.
+    if ($cache_lifetime = config('system.performance')->get('cache_lifetime')) {
+      // Clear expired items from the cache.
+      db_delete($this->bin)
+        ->condition('expire', CACHE_PERMANENT, '>')
+        ->condition('expire', REQUEST_TIME, '<')
+        ->execute();
+
+      // Clear CACHE_TEMPORARY items that are older than the minimum cache
+      // lifetime.
+      db_delete($this->bin)
+        ->condition('expire', CACHE_TEMPORARY)
+        ->condition('created', REQUEST_TIME - $cache_lifetime, '<')
+        ->execute();
+     }
+     else {
+       // No minimum cache lifetime, flush all expired and temporary cache
+       // entries now.
       db_delete($this->bin)
         ->condition('expire', CACHE_PERMANENT, '<>')
         ->condition('expire', REQUEST_TIME, '<')
@@ -234,38 +223,23 @@ class DatabaseBackend implements CacheBackendInterface {
    */
   function garbageCollection() {
     $cache_lifetime = config('system.performance')->get('cache_lifetime');
+    $config = config('system.performance');
 
-    // Clean-up the per-user cache expiration session data, so that the session
-    // handler can properly clean-up the session data for anonymous users.
-    if (isset($_SESSION['cache_expiration'])) {
-      $expire = REQUEST_TIME - $cache_lifetime;
-      foreach ($_SESSION['cache_expiration'] as $bin => $timestamp) {
-        if ($timestamp < $expire) {
-          unset($_SESSION['cache_expiration'][$bin]);
-        }
-      }
-      if (!$_SESSION['cache_expiration']) {
-        unset($_SESSION['cache_expiration']);
-      }
-    }
+    // Clear expired items from the cache.
+    db_delete($this->bin)
+      ->condition('expire', CACHE_PERMANENT, '>')
+      ->condition('expire', REQUEST_TIME, '<')
+      ->execute();
 
-    // Garbage collection of temporary items is only necessary when enforcing
-    // a minimum cache lifetime.
-    if (!$cache_lifetime) {
-      return;
-    }
-    // When cache lifetime is in force, avoid running garbage collection too
-    // often since this will remove temporary cache items indiscriminately.
-    $cache_flush = variable_get('cache_flush_' . $this->bin, 0);
-    if ($cache_flush && ($cache_flush + $cache_lifetime <= REQUEST_TIME)) {
-      // Reset the variable immediately to prevent a meltdown in heavy load situations.
-      variable_set('cache_flush_' . $this->bin, 0);
-      // Time to flush old cache data
-      db_delete($this->bin)
-        ->condition('expire', CACHE_PERMANENT, '<>')
-        ->condition('expire', $cache_flush, '<=')
-        ->execute();
-    }
+    // Clear old temporary cache items, 'old' is defined as older than the
+    // minimum cache lifetime, or 24 hours, whichever is the greatest.
+    $old = max($cache_lifetime, 86400);
+
+    // Clear CACHE_TEMPORARY items that are older than the minimum cache lifetime.
+    db_delete($this->bin)
+      ->condition('expire', CACHE_TEMPORARY)
+      ->condition('created', REQUEST_TIME - $old, '<')
+      ->execute();
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Cache/InstallBackend.php b/core/lib/Drupal/Core/Cache/InstallBackend.php
index f332fcc..fa6c7f5 100644
--- a/core/lib/Drupal/Core/Cache/InstallBackend.php
+++ b/core/lib/Drupal/Core/Cache/InstallBackend.php
@@ -32,7 +32,6 @@ use Exception;
  * administrator cleared the cache manually.
  */
 class InstallBackend extends DatabaseBackend {
-
   /**
    * Overrides Drupal\Core\Cache\CacheBackendInterface::get().
    */
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index e3517d7..8d7dce5 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -714,7 +714,7 @@ function system_schema() {
       ),
     ),
     'indexes' => array(
-      'expire' => array('expire'),
+      'expire_created' => array('expire', 'created'),
     ),
     'primary key' => array('cid'),
   );
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 200a335..2b7b6d2 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -3068,7 +3068,7 @@ function system_cron() {
   $core = array('cache', 'path', 'filter', 'page', 'form', 'menu');
   $cache_bins = array_merge(module_invoke_all('flush_caches'), $core);
   foreach ($cache_bins as $bin) {
-    cache($bin)->expire();
+    cache($bin)->garbageCollection();
   }
 
   // Cleanup the batch table and the queue for failed batches.
diff --git a/core/modules/system/tests/cache.test b/core/modules/system/tests/cache.test
index e5d4435..6964e40 100644
--- a/core/modules/system/tests/cache.test
+++ b/core/modules/system/tests/cache.test
@@ -317,6 +317,41 @@ class CacheClearCase extends CacheTestCase {
   }
 
   /**
+   * Test CACHE_TEMPORARY behaviour.
+   */
+  function testCacheTemporary() {
+    $cache = cache($this->default_bin);
+    // Set a permanent and temporary cache item.
+    $cache->set('test_cid_clear1', $this->default_value, CACHE_TEMPORARY);
+    $cache->set('test_cid_clear2', $this->default_value);
+    $this->assertTrue($this->checkCacheExists('test_cid_clear1', $this->default_value));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear2', $this->default_value));
+
+    // Expire all items in the bin, only the temporary item should be removed.
+    $cache->expire();
+    $this->assertFalse($this->checkCacheExists('test_cid_clear1', $this->default_value));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear2', $this->default_value));
+
+    // Set the temporary item again.
+    $cache->set('test_cid_clear1', $this->default_value, CACHE_TEMPORARY);
+
+    // Now call the garbageCollection method, neither item should be removed.
+    $cache->garbageCollection();
+    $this->assertTrue($this->checkCacheExists('test_cid_clear1', $this->default_value));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear2', $this->default_value));
+
+    // Set a minimum cache lifetime.
+    $cache->set('test_cid_clear1', $this->default_value, CACHE_TEMPORARY);
+    $this->setUpLifetime(300);
+
+    // Now after expiring the bin, neither the temporary nor permanent item
+    // should be removed.
+    $cache->expire();
+    $this->assertTrue($this->checkCacheExists('test_cid_clear1', $this->default_value));
+    $this->assertTrue($this->checkCacheExists('test_cid_clear2', $this->default_value));
+  }
+
+  /**
    * Test drupal_flush_all_caches().
    */
   function testFlushAllCaches() {
