diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb
index 7c7fd88222837fdee0252524c65cd47409f4b2e1..f7b29660e3e8e4e9726011beecdb99cd1ff7d994 100644
--- a/app/models/concerns/cache_markdown_field.rb
+++ b/app/models/concerns/cache_markdown_field.rb
@@ -129,28 +129,14 @@ def updated_cached_html_for(markdown_field)
   end
 
   def latest_cached_markdown_version
-    @latest_cached_markdown_version ||= (Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION << 16) | local_version
-  end
-
-  def local_version
-    # because local_markdown_version is stored in application_settings which
-    # uses cached_markdown_version too, we check explicitly to avoid
-    # endless loop
-    return local_markdown_version if respond_to?(:has_attribute?) && has_attribute?(:local_markdown_version)
-
-    settings = Gitlab::CurrentSettings.current_application_settings
-
-    # Following migrations are not properly isolated and
-    # use real models (by calling .ghost method), in these migrations
-    # local_markdown_version attribute doesn't exist yet, so we
-    # use a default value:
-    # db/migrate/20170825104051_migrate_issues_to_ghost_user.rb
-    # db/migrate/20171114150259_merge_requests_author_id_foreign_key.rb
-    if settings.respond_to?(:local_markdown_version)
-      settings.local_markdown_version
-    else
-      0
-    end
+    # because local_markdown_version is stored in application_settings which uses
+    # cached_markdown_version too, we check explicitly to avoid an endless loop.
+    local_version = local_markdown_version if respond_to?(:has_attribute?) && has_attribute?(:local_markdown_version)
+
+    # rubocop:disable Gitlab/ModuleWithInstanceVariables -- acceptable use case
+    # See https://docs.gitlab.com/ee/development/module_with_instance_variables.html#acceptable-use
+    @latest_cached_markdown_version ||= Gitlab::MarkdownCache.latest_cached_markdown_version(local_version: local_version)
+    # rubocop:enable Gitlab/ModuleWithInstanceVariables
   end
 
   def parent_user
diff --git a/lib/banzai/renderer.rb b/lib/banzai/renderer.rb
index 22b83bfd516c1ca4646f939474a10b052b0a9f8e..2703c12a8b6d842657b316a263d14b4a53776368 100644
--- a/lib/banzai/renderer.rb
+++ b/lib/banzai/renderer.rb
@@ -175,7 +175,11 @@ def self.cacheless_render(text, context = {})
     def self.full_cache_key(cache_key, pipeline_name)
       return unless cache_key
 
-      ["banzai", *cache_key, pipeline_name || :full]
+      [
+        "banzai",
+        *cache_key, pipeline_name || :full,
+        Gitlab::MarkdownCache.latest_cached_markdown_version(local_version: nil)
+      ]
     end
 
     # To map Rails.cache.read_multi results we need to know the Rails.cache.expanded_key.
diff --git a/lib/gitlab/markdown_cache.rb b/lib/gitlab/markdown_cache.rb
index b0b4a85128969bfa65ff49962402817f25c5ba45..e68e45668cc7e17e225ca290e2509d9bea705bae 100644
--- a/lib/gitlab/markdown_cache.rb
+++ b/lib/gitlab/markdown_cache.rb
@@ -13,8 +13,19 @@ module MarkdownCache
     # See: https://gitlab.com/gitlab-org/gitlab/-/issues/330313
     CACHE_COMMONMARK_VERSION       = 33
     CACHE_COMMONMARK_VERSION_START = 10
+    CACHE_COMMONMARK_VERSION_SHIFTED = CACHE_COMMONMARK_VERSION << 16
 
     BaseError = Class.new(StandardError)
     UnsupportedClassError = Class.new(BaseError)
+
+    # We could be called by a method that is inside the Gitlab::CurrentSettings
+    # object. In this case we need to pass in the local_markdown_version in order
+    # to avoid an infinite loop. See usaage in `app/models/concerns/cache_markdown_field.rb`
+    # Otherwise pass in `nil`
+    def self.latest_cached_markdown_version(local_version:)
+      local_version ||= Gitlab::CurrentSettings.current_application_settings.local_markdown_version
+
+      CACHE_COMMONMARK_VERSION_SHIFTED | local_version
+    end
   end
 end
diff --git a/spec/lib/banzai/object_renderer_spec.rb b/spec/lib/banzai/object_renderer_spec.rb
index ba065f4a457391845068fc5a5a4eb0231ae3c151..d17855a88e9bf7822fe4e0003948fb4f6ea92be5 100644
--- a/spec/lib/banzai/object_renderer_spec.rb
+++ b/spec/lib/banzai/object_renderer_spec.rb
@@ -13,7 +13,7 @@
     )
   end
 
-  let(:object) { Note.new(note: 'hello', note_html: '<p dir="auto">hello</p>', cached_markdown_version: Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION << 16) }
+  let(:object) { Note.new(note: 'hello', note_html: '<p dir="auto">hello</p>', cached_markdown_version: Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION_SHIFTED) }
 
   describe '#render' do
     context 'with cache' do
diff --git a/spec/lib/banzai/renderer_spec.rb b/spec/lib/banzai/renderer_spec.rb
index b34bdb0a2be1586e64bb0e90f9a13e4f1b4c5cde..c9eacb71507f05926bcaad6a7e5cc493614c2c55 100644
--- a/spec/lib/banzai/renderer_spec.rb
+++ b/spec/lib/banzai/renderer_spec.rb
@@ -151,6 +151,26 @@ def fake_cacheless_object
     end
   end
 
+  describe '#full_cache_key' do
+    it 'returns nil when no cache_key' do
+      expect(described_class.full_cache_key(nil, :full)).to be_nil
+    end
+
+    it 'returns a valid full cache key' do
+      cache_key = described_class.full_cache_key('my_cache_key', :emoji)
+      markdown_version = Gitlab::MarkdownCache.latest_cached_markdown_version(local_version: nil)
+
+      expect(cache_key).to eq ["banzai", "my_cache_key", :emoji, markdown_version]
+    end
+
+    it 'pipeline name defaults to :full' do
+      cache_key = described_class.full_cache_key('my_cache_key', nil)
+      markdown_version = Gitlab::MarkdownCache.latest_cached_markdown_version(local_version: nil)
+
+      expect(cache_key).to eq ["banzai", "my_cache_key", :full, markdown_version]
+    end
+  end
+
   describe 'instrumentation in render_result' do
     it 'calculates pipeline timing' do
       expect(ActiveSupport::Notifications).to receive(:monotonic_subscribe).with('call_filter.html_pipeline')
diff --git a/spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb b/spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb
index 081f1f4057b706468e2dcfe738955944d5dcb7ef..3b078c5472061440d38d0b72de0e53c872279ba8 100644
--- a/spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb
+++ b/spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb
@@ -18,7 +18,7 @@
     end
   end
 
-  let(:cache_version) { Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION << 16 }
+  let(:cache_version) { Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION_SHIFTED }
   let(:thing) do
     klass.create!(
       project_id: project.id, namespace_id: project.project_namespace_id,
diff --git a/spec/lib/gitlab/markdown_cache/redis/extension_spec.rb b/spec/lib/gitlab/markdown_cache/redis/extension_spec.rb
index 529b8745ee8fd1aa35a06b9046279e395d4170d2..4da8933d75fff4adad60d6d523c8c6e07720f65e 100644
--- a/spec/lib/gitlab/markdown_cache/redis/extension_spec.rb
+++ b/spec/lib/gitlab/markdown_cache/redis/extension_spec.rb
@@ -22,7 +22,7 @@ def cache_key
     end
   end
 
-  let(:cache_version) { Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION << 16 }
+  let(:cache_version) { Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION_SHIFTED }
   let(:thing) { klass.new(title: "`Hello`", description: "`World`") }
   let(:expected_cache_key) { "markdown_cache:cache-key" }
 
diff --git a/spec/lib/gitlab/markdown_cache_spec.rb b/spec/lib/gitlab/markdown_cache_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ac2aa1ead85e064a3b32148b6481514e07ef6783
--- /dev/null
+++ b/spec/lib/gitlab/markdown_cache_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::MarkdownCache, feature_category: :markdown do
+  it 'returns proper latest_cached_markdown_version' do
+    stub_application_setting(local_markdown_version: 2)
+
+    expect(described_class.latest_cached_markdown_version(local_version: nil))
+      .to eq described_class::CACHE_COMMONMARK_VERSION_SHIFTED | 2
+  end
+
+  it 'uses passed in local_version' do
+    stub_application_setting(local_markdown_version: 2)
+
+    expect(described_class.latest_cached_markdown_version(local_version: 5))
+      .to eq described_class::CACHE_COMMONMARK_VERSION_SHIFTED | 5
+  end
+end
diff --git a/spec/models/concerns/cache_markdown_field_spec.rb b/spec/models/concerns/cache_markdown_field_spec.rb
index 97e43f3494c53f8bda23cecbfcdf1c8ca61c81df..90d166dbfb68d2ba5438f5a473d2a1312ecdc518 100644
--- a/spec/models/concerns/cache_markdown_field_spec.rb
+++ b/spec/models/concerns/cache_markdown_field_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-RSpec.describe CacheMarkdownField, :clean_gitlab_redis_cache do
+RSpec.describe CacheMarkdownField, :clean_gitlab_redis_cache, feature_category: :markdown do
   let(:ar_class) do
     Class.new(ActiveRecord::Base) do
       self.table_name = 'issues'
@@ -46,7 +46,7 @@ def cache_key
   let(:updated_markdown) { '`Bar`' }
   let(:updated_html) { '<p dir="auto"><code>Bar</code></p>' }
 
-  let(:cache_version) { Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION << 16 }
+  let(:cache_version) { Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION_SHIFTED }
 
   def thing_subclass(klass, *extra_attributes)
     Class.new(klass) { attr_accessor(*extra_attributes) }
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 14994d90b6cebb8bff6a79e2172317d41f988a85..2c6ac42d26bc4873000df5396047587dd0d2b963 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -2196,7 +2196,9 @@ def create_deployment_with_stop_action(status, pipeline, stop_action_name)
     end
 
     it 'caches the freeze periods' do
-      expect(Gitlab::SafeRequestStore).to receive(:fetch)
+      allow(Gitlab::SafeRequestStore).to receive(:fetch).and_call_original
+
+      expect(Gitlab::SafeRequestStore).to receive(:fetch).with("project:#{project.id}:freeze_periods_for_environments")
         .at_least(:once)
         .and_return([freeze_period])
 
diff --git a/spec/models/resource_label_event_spec.rb b/spec/models/resource_label_event_spec.rb
index 4c1a491c40bf4a9ae300dcb36fb2885718ca96b3..bfcb17626da2041c530ade5d8c5260fbecc0cc7c 100644
--- a/spec/models/resource_label_event_spec.rb
+++ b/spec/models/resource_label_event_spec.rb
@@ -85,13 +85,13 @@
     end
 
     it 'returns true if markdown is outdated' do
-      subject.attributes = { cached_markdown_version: ((Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION - 1) << 16) | 0 }
+      subject.attributes = { cached_markdown_version: Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION_SHIFTED + 1 }
 
       expect(subject.outdated_markdown?).to be true
     end
 
     it 'returns false if label and reference are set' do
-      subject.attributes = { reference: 'whatever', cached_markdown_version: Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION << 16 }
+      subject.attributes = { reference: 'whatever', cached_markdown_version: Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION_SHIFTED }
 
       expect(subject.outdated_markdown?).to be false
     end
diff --git a/spec/support/shared_examples/models/mentionable_shared_examples.rb b/spec/support/shared_examples/models/mentionable_shared_examples.rb
index 5f66e2b31b92c33cd8c25cf177e7fba5c2ee1bd8..cecd9e7d02e40e74bbca4d586334a718639b7f78 100644
--- a/spec/support/shared_examples/models/mentionable_shared_examples.rb
+++ b/spec/support/shared_examples/models/mentionable_shared_examples.rb
@@ -146,7 +146,7 @@
     context 'when the markdown cache is stale' do
       before do
         expect(subject).to receive(:latest_cached_markdown_version).at_least(:once) do
-          (Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION + 1) << 16
+          Gitlab::MarkdownCache::CACHE_COMMONMARK_VERSION_SHIFTED + 1
         end
       end