diff --git a/core/lib/Drupal/Core/Cache/CacheOptionalInterface.php b/core/lib/Drupal/Core/Cache/CacheOptionalInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..e27545a69c5f30ad391fc171a989c2c05bf0e9cf
--- /dev/null
+++ b/core/lib/Drupal/Core/Cache/CacheOptionalInterface.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Drupal\Core\Cache;
+
+/**
+ * Indicates that caching is optional.
+ *
+ * This interface can be used to suggest that certain implementations are fast
+ * enough that they do not require additional caching.
+ *
+ * If and how exactly this is implemented and used depends on the specific
+ * system.
+ *
+ * Examples:
+ *  - If all active access policies implement this interface,
+ *    \Drupal\Core\Session\AccessPolicyProcessor will skip the persistent cache.
+ */
+interface CacheOptionalInterface {
+
+}
diff --git a/core/lib/Drupal/Core/Session/AccessPolicyProcessor.php b/core/lib/Drupal/Core/Session/AccessPolicyProcessor.php
index 6dc0e359bc0690410c4d816c88a94d7299fb3810..d381fcc5d18de6b414fc1f2f2730d5d55dd86bef 100644
--- a/core/lib/Drupal/Core/Session/AccessPolicyProcessor.php
+++ b/core/lib/Drupal/Core/Session/AccessPolicyProcessor.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Session;
 
+use Drupal\Core\Cache\CacheOptionalInterface;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Cache\VariationCacheInterface;
@@ -82,7 +83,7 @@ public function processAccessPolicies(AccountInterface $account, string $scope =
       }
 
       // Retrieve the permissions from the persistent cache if available.
-      if ($cache = $this->variationCache->get($cache_keys, $initial_cacheability)) {
+      if ($this->needsPersistentCache() && $cache = $this->variationCache->get($cache_keys, $initial_cacheability)) {
         $calculated_permissions = $cache->data;
         $cacheability = CacheableMetadata::createFromObject($calculated_permissions);
 
@@ -134,7 +135,9 @@ public function processAccessPolicies(AccountInterface $account, string $scope =
       // we had stored a CalculatedPermissions object, we would no longer be
       // able to ask for its cache contexts.
       $cacheability = CacheableMetadata::createFromObject($calculated_permissions);
-      $this->variationCache->set($cache_keys, $calculated_permissions, $cacheability, $initial_cacheability);
+      if ($this->needsPersistentCache()) {
+        $this->variationCache->set($cache_keys, $calculated_permissions, $cacheability, $initial_cacheability);
+      }
 
       // Then convert the calculated permissions to an immutable value object
       // and store it in the static cache so that we don't have to do the same
@@ -200,4 +203,20 @@ protected function validateScope(string $scope, CalculatedPermissionsInterface $
     return empty($actual_scopes) || $actual_scopes === [$scope];
   }
 
+  /**
+   * Returns whether the persistent cache is necessary.
+   *
+   * @return bool
+   *   TRUE if cache should be used (at least one policy requires cache), FALSE
+   *   if not.
+   */
+  protected function needsPersistentCache(): bool {
+    foreach ($this->accessPolicies as $access_policy) {
+      if (!$access_policy instanceof CacheOptionalInterface) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Session/SuperUserAccessPolicy.php b/core/lib/Drupal/Core/Session/SuperUserAccessPolicy.php
index d8692e2728fbb2b457198159ff311b968b2c67c5..2b9cd3043648f854a1baeae38022524dca0c949c 100644
--- a/core/lib/Drupal/Core/Session/SuperUserAccessPolicy.php
+++ b/core/lib/Drupal/Core/Session/SuperUserAccessPolicy.php
@@ -4,10 +4,12 @@
 
 namespace Drupal\Core\Session;
 
+use Drupal\Core\Cache\CacheOptionalInterface;
+
 /**
  * Grants user 1 an all access pass.
  */
-final class SuperUserAccessPolicy extends AccessPolicyBase {
+final class SuperUserAccessPolicy extends AccessPolicyBase implements CacheOptionalInterface {
 
   /**
    * {@inheritdoc}
diff --git a/core/lib/Drupal/Core/Session/UserRolesAccessPolicy.php b/core/lib/Drupal/Core/Session/UserRolesAccessPolicy.php
index 9e972d802abe51fa0e8bae0ce01683095738c539..18102b1eb4b25b09a3e30736301cd6bb1f31b09c 100644
--- a/core/lib/Drupal/Core/Session/UserRolesAccessPolicy.php
+++ b/core/lib/Drupal/Core/Session/UserRolesAccessPolicy.php
@@ -4,12 +4,13 @@
 
 namespace Drupal\Core\Session;
 
+use Drupal\Core\Cache\CacheOptionalInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 
 /**
  * Grants permissions based on a user's roles.
  */
-final class UserRolesAccessPolicy extends AccessPolicyBase {
+final class UserRolesAccessPolicy extends AccessPolicyBase implements CacheOptionalInterface {
 
   public function __construct(protected EntityTypeManagerInterface $entityTypeManager) {}
 
diff --git a/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php b/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php
index ddd9bc7d684e3070d89ff9988ec0fc04fa6cc310..85ce146e2d256e04ccbab67690ebbec0eb90b4d5 100644
--- a/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php
+++ b/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php
@@ -75,12 +75,11 @@ public function testLogin(): void {
       'QueryCount' => 4,
       'CacheGetCount' => 61,
       'CacheGetCountByBin' => [
-        'config' => 10,
+        'config' => 11,
         'data' => 6,
-        'access_policy' => 1,
+        'discovery' => 11,
         'bootstrap' => 6,
         'dynamic_page_cache' => 2,
-        'discovery' => 11,
         'render' => 23,
         'menu' => 1,
         'default' => 1,
@@ -91,7 +90,7 @@ public function testLogin(): void {
       ],
       'CacheDeleteCount' => 0,
       'CacheTagChecksumCount' => 3,
-      'CacheTagIsValidCount' => 31,
+      'CacheTagIsValidCount' => 30,
       'CacheTagInvalidationCount' => 0,
       'ScriptCount' => 2,
       'ScriptBytes' => 215500,
diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php
index b6dc3a500a33b203579f6c7a222d0cadb95b31d5..24c7193b0ee0cd61359ecc26adefbcf09440d33f 100644
--- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php
+++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php
@@ -53,9 +53,8 @@ public function testFrontPageAuthenticatedWarmCache(): void {
       'QueryCount' => 4,
       'CacheGetCount' => 40,
       'CacheGetCountByBin' => [
-        'config' => 20,
+        'config' => 22,
         'discovery' => 5,
-        'access_policy' => 2,
         'data' => 7,
         'bootstrap' => 4,
         'dynamic_page_cache' => 2,
@@ -63,9 +62,9 @@ public function testFrontPageAuthenticatedWarmCache(): void {
       'CacheSetCount' => 0,
       'CacheDeleteCount' => 0,
       'CacheTagChecksumCount' => 0,
-      'CacheTagIsValidCount' => 11,
+      'CacheTagIsValidCount' => 10,
       'CacheTagInvalidationCount' => 0,
-      'CacheTagLookupQueryCount' => 6,
+      'CacheTagLookupQueryCount' => 5,
       'ScriptCount' => 1,
       'ScriptBytes' => 123850,
       'StylesheetCount' => 2,
diff --git a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
index 9026bca418ae28c7eab36085f128ac9d9c47db5b..ecc905112b37b7b64c7df4bcd8a5ff4591919796 100644
--- a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
+++ b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
@@ -130,12 +130,11 @@ protected function testAnonymous(): void {
       'CacheGetCount' => 122,
       'CacheGetCountByBin' => [
         'page' => 1,
-        'config' => 20,
+        'config' => 21,
         'data' => 8,
-        'access_policy' => 1,
+        'discovery' => 38,
         'bootstrap' => 8,
         'dynamic_page_cache' => 2,
-        'discovery' => 38,
         'render' => 35,
         'default' => 5,
         'entity' => 2,
@@ -144,14 +143,13 @@ protected function testAnonymous(): void {
       'CacheSetCount' => 45,
       'CacheDeleteCount' => 0,
       'CacheTagChecksumCount' => 37,
-      'CacheTagIsValidCount' => 43,
+      'CacheTagIsValidCount' => 42,
       'CacheTagInvalidationCount' => 0,
       'CacheTagLookupQueryCount' => 29,
       'CacheTagGroupedLookups' => [
         ['route_match'],
-        ['access_policies', 'config:user.role.anonymous'],
-        ['routes'],
         ['entity_types'],
+        ['routes'],
         ['config:views.view.frontpage'],
         ['config:core.extension', 'views_data'],
         ['entity_field_info'],
@@ -177,6 +175,7 @@ protected function testAnonymous(): void {
         ['config:block.block.stark_syndicate'],
         ['config:block.block.stark_content', 'config:block.block.stark_page_title', 'config:block_list', 'http_response'],
         ['library_info'],
+        ['config:user.role.anonymous'],
       ],
       'StylesheetCount' => 1,
       'StylesheetBytes' => 3450,
@@ -212,7 +211,7 @@ protected function testAnonymous(): void {
     $recorded_queries = $performance_data->getQueries();
     $this->assertSame($expected_queries, $recorded_queries);
     $this->assertCountBetween(24, 25, $performance_data->getCacheTagChecksumCount());
-    $this->assertCountBetween(39, 40, $performance_data->getCacheTagIsValidCount());
+    $this->assertCountBetween(38, 39, $performance_data->getCacheTagIsValidCount());
     $expected = [
       'QueryCount' => 10,
       'CacheGetCount' => 92,
@@ -224,7 +223,6 @@ protected function testAnonymous(): void {
         ['route_match'],
         ['entity_types'],
         ['entity_field_info', 'node_values'],
-        ['access_policies', 'config:user.role.anonymous'],
         ['routes'],
         ['entity_bundles'],
         ['user_values'],
@@ -246,6 +244,7 @@ protected function testAnonymous(): void {
         ['config:block.block.stark_syndicate'],
         ['config:block.block.stark_content', 'config:block.block.stark_page_title', 'config:block_list', 'http_response'],
         ['library_info'],
+        ['config:user.role.anonymous'],
       ],
       'StylesheetCount' => 1,
       'StylesheetBytes' => 3150,
@@ -283,9 +282,9 @@ protected function testAnonymous(): void {
       'CacheSetCount' => 17,
       'CacheDeleteCount' => 0,
       'CacheTagChecksumCount' => 23,
-      'CacheTagIsValidCount' => 32,
+      'CacheTagIsValidCount' => 31,
       'CacheTagInvalidationCount' => 0,
-      'CacheTagLookupQueryCount' => 24,
+      'CacheTagLookupQueryCount' => 23,
       'StylesheetCount' => 1,
       'StylesheetBytes' => 3150,
     ];
@@ -340,15 +339,14 @@ protected function testLogin(): void {
       'CacheSetCount' => 1,
       'CacheDeleteCount' => 1,
       'CacheTagChecksumCount' => 1,
-      'CacheTagIsValidCount' => 37,
+      'CacheTagIsValidCount' => 35,
       'CacheTagInvalidationCount' => 0,
-      'CacheTagLookupQueryCount' => 28,
+      'CacheTagLookupQueryCount' => 26,
       'CacheTagGroupedLookups' => [
         // Form submission and login.
         ['route_match'],
         ['routes'],
         ['entity_types'],
-        ['access_policies', 'config:user.role.anonymous'],
         ['entity_field_info', 'user_values'],
         // The user page after the redirect.
         ['route_match'],
@@ -356,7 +354,6 @@ protected function testLogin(): void {
         ['entity_field_info'],
         ['entity_bundles'],
         ['user_values'],
-        ['access_policies', 'config:user.role.authenticated'],
         ['routes'],
         ['rendered', 'user:2', 'user_view'],
         ['block_view', 'config:block.block.stark_site_branding', 'config:system.site'],
@@ -368,7 +365,7 @@ protected function testLogin(): void {
         ['config:block.block.stark_breadcrumbs'],
         ['config:block.block.stark_primary_admin_actions'],
         ['config:block.block.stark_messages'],
-        ['config:block.block.stark_primary_local_tasks', 'local_task'],
+        ['access_policies', 'config:block.block.stark_primary_local_tasks', 'config:user.role.authenticated', 'local_task'],
         ['config:block.block.stark_secondary_local_tasks'],
         ['config:block.block.stark_help'],
         ['config:block.block.stark_powered'],
@@ -430,9 +427,9 @@ protected function testLoginBlock(): void {
       'CacheSetCount' => 1,
       'CacheDeleteCount' => 1,
       'CacheTagChecksumCount' => 1,
-      'CacheTagIsValidCount' => 43,
+      'CacheTagIsValidCount' => 41,
       'CacheTagInvalidationCount' => 0,
-      'CacheTagLookupQueryCount' => 29,
+      'CacheTagLookupQueryCount' => 27,
     ];
     $this->assertMetrics($expected, $performance_data);
   }