diff --git a/core/core.services.yml b/core/core.services.yml
index 5a9cd6e..60673fa 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -140,6 +140,16 @@ services:
   cache.backend.php:
     class: Drupal\Core\Cache\PhpBackendFactory
     arguments: ['@cache_tags.invalidator.checksum']
+  cache.backend.memory:
+    class: Drupal\Core\Cache\MemoryBackendFactory
+    arguments: ['@cache_tags.invalidator.checksum']
+  # A special cache bin that by default does not persist beyond the length of the request.
+  cache.static:
+    class: Drupal\Core\Cache\CacheBackendInterface
+    tags:
+      - { name: cache.bin, default_backend: cache.backend.memory }
+    factory: cache_factory:get
+    arguments: [memory]
   cache.bootstrap:
     class: Drupal\Core\Cache\CacheBackendInterface
     tags:
@@ -1238,7 +1248,7 @@ services:
     arguments: ['@current_user', '@session_handler.write_safe']
   user_permissions_hash_generator:
     class: Drupal\Core\Session\PermissionsHashGenerator
-    arguments: ['@private_key', '@cache.default']
+    arguments: ['@private_key', '@cache.default', '@cache.static']
   current_user:
     class: Drupal\Core\Session\AccountProxy
   session_configuration:
diff --git a/core/lib/Drupal/Core/Session/PermissionsHashGenerator.php b/core/lib/Drupal/Core/Session/PermissionsHashGenerator.php
index f176afd..5c79d04 100644
--- a/core/lib/Drupal/Core/Session/PermissionsHashGenerator.php
+++ b/core/lib/Drupal/Core/Session/PermissionsHashGenerator.php
@@ -26,13 +26,20 @@ class PermissionsHashGenerator implements PermissionsHashGeneratorInterface {
   protected $privateKey;
 
   /**
-   * The cache backend interface to use for the permission hash cache.
+   * The cache backend interface to use for the persistent cache.
    *
    * @var \Drupal\Core\Cache\CacheBackendInterface
    */
   protected $cache;
 
   /**
+   * The cache backend interface to use for the static cache.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface
+   */
+  protected $static;
+
+  /**
    * Constructs a PermissionsHashGenerator object.
    *
    * @param \Drupal\Core\PrivateKey $private_key
@@ -40,9 +47,10 @@ class PermissionsHashGenerator implements PermissionsHashGeneratorInterface {
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
    *   The cache backend interface to use for the permission hash cache.
    */
-  public function __construct(PrivateKey $private_key, CacheBackendInterface $cache) {
+  public function __construct(PrivateKey $private_key, CacheBackendInterface $cache, CacheBackendInterface $static) {
     $this->privateKey = $private_key;
     $this->cache = $cache;
+    $this->static = $static;
   }
 
   /**
@@ -54,13 +62,20 @@ public function generate(AccountInterface $account) {
     $sorted_roles = $account->getRoles();
     sort($sorted_roles);
     $role_list = implode(',', $sorted_roles);
-    if ($cache = $this->cache->get("user_permissions_hash:$role_list")) {
-      $permissions_hash = $cache->data;
+    $cid = "user_permissions_hasn:$role_list";
+    if ($static_cache = $this->static->get($cid)) {
+      return $static_cache->data;
     }
     else {
-      $permissions_hash = $this->doGenerate($sorted_roles);
       $tags = Cache::buildTags('config:user.role', $sorted_roles, '.');
-      $this->cache->set("user_permissions_hash:$role_list", $permissions_hash, Cache::PERMANENT, $tags);
+      if ($cache = $this->cache->get("user_permissions_hash:$role_list")) {
+        $permissions_hash = $cache->data;
+        $this->static->set($cid, $permissions_hash, Cache::PERMANENT, $tags);
+      }
+      else {
+        $permissions_hash = $this->doGenerate($sorted_roles);
+        $this->cache->set("user_permissions_hash:$role_list", $permissions_hash, Cache::PERMANENT, $tags);
+      }
     }
 
     return $permissions_hash;
diff --git a/core/modules/user/src/Tests/UserPermissionsTest.php b/core/modules/user/src/Tests/UserPermissionsTest.php
index 9108fc3..4cc6877 100644
--- a/core/modules/user/src/Tests/UserPermissionsTest.php
+++ b/core/modules/user/src/Tests/UserPermissionsTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\user\Tests;
 
+use Drupal\Core\Cache\Cache;
 use Drupal\simpletest\WebTestBase;
 use Drupal\user\RoleInterface;
 use Drupal\user\Entity\Role;
@@ -56,6 +57,7 @@ function testUserPermissionChanges() {
     // Create an additional role and mark it as admin role.
     Role::create(['is_admin' => TRUE, 'id' => 'administrator', 'label' => 'Administrator'])->save();
     $storage->resetCache();
+    Cache::invalidateTags(["config:user.role.$this->rid"]);
 
     $this->drupalLogin($this->adminUser);
     $rid = $this->rid;
@@ -70,6 +72,7 @@ function testUserPermissionChanges() {
     $this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions'));
     $this->assertText(t('The changes have been saved.'), 'Successful save message displayed.');
     $storage->resetCache();
+    Cache::invalidateTags(["config:user.role.$this->rid"]);
     $this->assertTrue($account->hasPermission('administer users'), 'User now has "administer users" permission.');
     $current_permissions_hash = $permissions_hash_generator->generate($account);
     $this->assertIdentical($current_permissions_hash, $permissions_hash_generator->generate($this->loggedInUser));
@@ -83,6 +86,7 @@ function testUserPermissionChanges() {
     $this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions'));
     $this->assertText(t('The changes have been saved.'), 'Successful save message displayed.');
     $storage->resetCache();
+    Cache::invalidateTags(["config:user.role.$this->rid"]);
     $this->assertFalse($account->hasPermission('access user profiles'), 'User no longer has "access user profiles" permission.');
     $current_permissions_hash = $permissions_hash_generator->generate($account);
     $this->assertIdentical($current_permissions_hash, $permissions_hash_generator->generate($this->loggedInUser));
diff --git a/core/tests/Drupal/Tests/Core/Session/PermissionsHashTest.php b/core/tests/Drupal/Tests/Core/Session/PermissionsHashTest.php
index 2bc202c..d760daa 100644
--- a/core/tests/Drupal/Tests/Core/Session/PermissionsHashTest.php
+++ b/core/tests/Drupal/Tests/Core/Session/PermissionsHashTest.php
@@ -112,7 +112,7 @@ protected function setUp() {
       ->disableOriginalConstructor()
       ->getMock();
 
-    $this->permissionsHash = new PermissionsHashGenerator($this->privateKey, $this->cache);
+    $this->permissionsHash = new PermissionsHashGenerator($this->privateKey, $this->cache, new \Drupal\Core\Cache\MemoryBackend('test'));
   }
 
   /**
@@ -130,9 +130,9 @@ public function testGenerate() {
   }
 
   /**
-   * Tests the generate method with cache returned.
+   * Tests the generate method with persistent cache returned.
    */
-  public function testGenerateCache() {
+  public function testGeneratePersistentCache() {
     // Set expectations for the mocked cache backend.
     $expected_cid = 'user_permissions_hash:administrator,authenticated';
 
@@ -150,6 +150,27 @@ public function testGenerateCache() {
   }
 
   /**
+   * Tests the generate method with static cache returned.
+   */
+  public function testGenerateStaticCache() {
+    // Set expectations for the mocked cache backend.
+    $expected_cid = 'user_permissions_hash:administrator,authenticated';
+
+    $mock_cache = new \stdClass();
+    $mock_cache->data = 'test_hash_here';
+
+    $this->permissionsHasn = new PermissionsHashGenerator($this->privateKey, new \Drupal\Core\Cache\MemoryBackend('test'), $this->cache);
+    $this->cache->expects($this->once())
+      ->method('get')
+      ->with($expected_cid)
+      ->will($this->returnValue($mock_cache));
+    $this->cache->expects($this->never())
+      ->method('set');
+
+    $this->permissionsHash->generate($this->account1);
+  }
+
+  /**
    * Tests the generate method with no cache returned.
    */
   public function testGenerateNoCache() {
