diff --git a/core/core.services.yml b/core/core.services.yml
index 5e63508..91dd43a 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -207,7 +207,7 @@ services:
     tags:
       - { name: cache.bin }
     factory: cache_factory:get
-    arguments: [default]
+    arguments: [default, ['maximum_permanent_ttl', 86400]]
   cache.entity:
     class: Drupal\Core\Cache\CacheBackendInterface
     tags:
diff --git a/core/lib/Drupal/Core/Cache/ChainedFastBackendFactory.php b/core/lib/Drupal/Core/Cache/ChainedFastBackendFactory.php
index ca38ca0..e979f43 100644
--- a/core/lib/Drupal/Core/Cache/ChainedFastBackendFactory.php
+++ b/core/lib/Drupal/Core/Cache/ChainedFastBackendFactory.php
@@ -12,7 +12,7 @@
 /**
  * Defines the chained fast cache backend factory.
  */
-class ChainedFastBackendFactory implements CacheFactoryInterface {
+class ChainedFastBackendFactory implements ConfigurableCacheFactoryInterface {
 
   use ContainerAwareTrait;
 
@@ -68,21 +68,16 @@ public function __construct(Settings $settings = NULL, $consistent_service_name
   }
 
   /**
-   * Instantiates a chained, fast cache backend class for a given cache bin.
-   *
-   * @param string $bin
-   *   The cache bin for which a cache backend object should be returned.
-   *
-   * @return \Drupal\Core\Cache\CacheBackendInterface
-   *   The cache backend object associated with the specified bin.
+   * {@inheritdoc}
    */
-  public function get($bin) {
+  public function get($bin, array $options = []) {
     // Use the chained backend only if there is a fast backend available;
     // otherwise, just return the consistent backend directly.
     if (isset($this->fastServiceName)) {
       return new ChainedFastBackend(
-        $this->container->get($this->consistentServiceName)->get($bin),
-        $this->container->get($this->fastServiceName)->get($bin),
+        // @todo: check interface.
+        $this->container->get($this->consistentServiceName)->get($bin, $options),
+        $this->container->get($this->fastServiceName)->get($bin, $options),
         $bin
       );
     }
diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
index db5c2f0..26db042 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
@@ -19,7 +19,7 @@
  *
  * @ingroup cache
  */
-class DatabaseBackend implements CacheBackendInterface {
+class DatabaseBackend implements CacheBackendInterface, ConfigurablePermanentTtlInterface {
 
   /**
    * @var string
@@ -42,6 +42,11 @@ class DatabaseBackend implements CacheBackendInterface {
   protected $checksumProvider;
 
   /**
+   * The minimum permanent TTL.
+   */
+  protected $minimumPermanentTtl = CacheBackendInterface::CACHE_PERMANENT;
+
+  /**
    * Constructs a DatabaseBackend object.
    *
    * @param \Drupal\Core\Database\Connection $connection
@@ -194,8 +199,15 @@ protected function doSetMultiple(array $items) {
     $values = array();
 
     foreach ($items as $cid => $item) {
+      if (!isset($item['expire']) || $item['expire'] === CacheBackendInterface::CACHE_PERMANENT)  {
+        if ($this->minimumPermanentTtl === CacheBackendInterface::CACHE_PERMANENT) {
+          $item['expire'] = CacheBackendInterface::CACHE_PERMANENT;
+        }
+        else {
+          $item['expire'] = $this->calculatePermanentExpire();
+        }
+      }
       $item += array(
-        'expire' => CacheBackendInterface::CACHE_PERMANENT,
         'tags' => array(),
       );
 
@@ -240,6 +252,14 @@ protected function doSetMultiple(array $items) {
   }
 
   /**
+   * Calculate permanent expiry.
+   */
+  protected function calculatePermanentExpire() {
+    $minimum = $this->minimumPermanentTtl;
+    return rand($minimum, $minimum * 1.5) + REQUEST_TIME;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function delete($cid) {
@@ -356,6 +376,13 @@ public function removeBin() {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function setMinimumPermanentTtl($ttl) {
+    $this->minimumPermanentTtl = $ttl;
+  }
+
+  /**
    * Check if the cache bin exists and create it if not.
    */
   protected function ensureBinExists() {
diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php b/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php
index 59b0b22..325bd49 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php
@@ -9,7 +9,7 @@
 
 use Drupal\Core\Database\Connection;
 
-class DatabaseBackendFactory implements CacheFactoryInterface {
+class DatabaseBackendFactory implements ConfigurableCacheFactoryInterface {
 
   /**
    * The database connection.
@@ -39,16 +39,14 @@ function __construct(Connection $connection, CacheTagsChecksumInterface $checksu
   }
 
   /**
-   * Gets DatabaseBackend for the specified cache bin.
-   *
-   * @param $bin
-   *   The cache bin for which the object is created.
-   *
-   * @return \Drupal\Core\Cache\DatabaseBackend
-   *   The cache backend object for the specified cache bin.
+   * {@inheritdoc}
    */
-  function get($bin) {
-    return new DatabaseBackend($this->connection, $this->checksumProvider, $bin);
+  function get($bin, array $options = []) {
+    $class =  new DatabaseBackend($this->connection, $this->checksumProvider, $bin);
+    if (isset($options['minimum_permanent_ttl'])) {
+      $class->setMinimumPermanentTtl($options['minimum_permanent_ttl']);
+    }
+    return $class;
   }
 
 }
diff --git a/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php b/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php
index 934fe81..89812a3 100644
--- a/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php
+++ b/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\Cache;
 
+use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Cache\DatabaseBackend;
 
 /**
@@ -51,6 +52,21 @@ public function testSetGet() {
     $cached_value_short = $this->randomMachineName();
     $backend->set($cid_short, $cached_value_short);
     $this->assertIdentical($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id.");
+
+  }
+
+  /**
+   * Test minimumPermanentTtl.
+   */
+  function testMinimumPermanentTtl() {
+    $backend = $this->getCacheBackend();
+    $backend->setMinimumPermanentTtl(2);
+    $cid = 'test';
+    $value = 'test';
+    $backend->set($cid, $value);
+    $item = $backend->get($cid);
+    $this->assertTrue($item->expire !== CacheBackendInterface::CACHE_PERMANENT);
+    $this->assertTrue($item->expire <= REQUEST_TIME + 2 * 1.5);
   }
 
 }
