diff --git a/app/events/repositories/default_branch_changed_event.rb b/app/events/repositories/default_branch_changed_event.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3519fb4be86b94cac13c97687552f5ae4cc74071
--- /dev/null
+++ b/app/events/repositories/default_branch_changed_event.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Repositories
+  class DefaultBranchChangedEvent < ::Gitlab::EventStore::Event
+    def schema
+      {
+        'type' => 'object',
+        'properties' => {
+          'container_id' => { 'type' => 'integer' },
+          'container_type' => { 'type' => 'string' }
+        },
+        'required' => %w[container_id container_type]
+      }
+    end
+  end
+end
diff --git a/app/models/concerns/has_repository.rb b/app/models/concerns/has_repository.rb
index d614d6c4584ec7bf551e318ada3708add4eeac9c..0e7381882b5a4476a23e9945e34f1a497c63b801 100644
--- a/app/models/concerns/has_repository.rb
+++ b/app/models/concerns/has_repository.rb
@@ -119,6 +119,9 @@ def repository_size_checker
 
   def after_repository_change_head
     reload_default_branch
+
+    Gitlab::EventStore.publish(
+      Repositories::DefaultBranchChangedEvent.new(data: { container_id: id, container_type: self.class.name }))
   end
 
   def after_change_head_branch_does_not_exist(branch)
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 10da221b6d9ac9b32525680b62ed653bde5bee1c..b54653c52377b96cee03d1ce803fd696245a0338 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -565,6 +565,8 @@
   - 1
 - - sbom_reports
   - 1
+- - search_elastic_default_branch_changed
+  - 1
 - - search_elastic_group_association_deletion
   - 1
 - - search_namespace_index_integrity
diff --git a/ee/app/models/concerns/elastic/wiki_repositories_search.rb b/ee/app/models/concerns/elastic/wiki_repositories_search.rb
index e82b78914962a933108841368de516b594206824..85534ca9dce34bc73d0e1643fc30307a4112c482 100644
--- a/ee/app/models/concerns/elastic/wiki_repositories_search.rb
+++ b/ee/app/models/concerns/elastic/wiki_repositories_search.rb
@@ -9,6 +9,8 @@ module WikiRepositoriesSearch
     delegate(:delete_index_for_commits_and_blobs, :elastic_search, to: :__elasticsearch__)
 
     def index_wiki_blobs
+      return unless is_a?(::ProjectWiki) || ::Wiki.use_separate_indices?
+
       ElasticWikiIndexerWorker.perform_async(container.id, container.class.name)
     end
   end
diff --git a/ee/app/services/ee/git/wiki_push_service.rb b/ee/app/services/ee/git/wiki_push_service.rb
index dd6a511df60f1d121d88f5684be6900e4a2c0552..501c73361a394075d7fb413649d39a4d4db0838d 100644
--- a/ee/app/services/ee/git/wiki_push_service.rb
+++ b/ee/app/services/ee/git/wiki_push_service.rb
@@ -9,8 +9,6 @@ module WikiPushService
       def execute
         super
 
-        return unless wiki.is_a?(::ProjectWiki) || ::Wiki.use_separate_indices?
-
         return unless wiki.container.use_elasticsearch? && default_branch_changes.any?
 
         wiki.index_wiki_blobs
diff --git a/ee/app/workers/all_queues.yml b/ee/app/workers/all_queues.yml
index a5cd2294230757fb2dae857891a89b27cdc8ed12..2a1ebe99894dd5cb04f03aeece389b5dffd55451 100644
--- a/ee/app/workers/all_queues.yml
+++ b/ee/app/workers/all_queues.yml
@@ -1794,6 +1794,15 @@
   :weight: 1
   :idempotent: true
   :tags: []
+- :name: search_elastic_default_branch_changed
+  :worker_name: Search::ElasticDefaultBranchChangedWorker
+  :feature_category: :global_search
+  :has_external_dependencies: false
+  :urgency: :low
+  :resource_boundary: :unknown
+  :weight: 1
+  :idempotent: true
+  :tags: []
 - :name: search_elastic_group_association_deletion
   :worker_name: Search::ElasticGroupAssociationDeletionWorker
   :feature_category: :global_search
diff --git a/ee/app/workers/search/elastic_default_branch_changed_worker.rb b/ee/app/workers/search/elastic_default_branch_changed_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1534e015dd3d294ea9034aa34f1afa9dfd511d42
--- /dev/null
+++ b/ee/app/workers/search/elastic_default_branch_changed_worker.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Search
+  class ElasticDefaultBranchChangedWorker
+    include ApplicationWorker
+    include Gitlab::EventStore::Subscriber
+
+    data_consistency :delayed
+    feature_category :global_search
+    urgency :low
+    idempotent!
+
+    def handle_event(event)
+      return unless ::Gitlab::CurrentSettings.elasticsearch_indexing?
+
+      klass = event.data[:container_type].safe_constantize
+      object = klass.find_by_id(event.data[:container_id])
+      return unless object&.try(:use_elasticsearch?)
+
+      enqueue_indexing(object)
+    end
+
+    private
+
+    def enqueue_indexing(object)
+      case object
+      when Project
+        object.repository.index_commits_and_blobs
+      when GroupWiki, ProjectWiki
+        object.index_wiki_blobs
+      end
+    end
+  end
+end
diff --git a/ee/lib/ee/gitlab/event_store.rb b/ee/lib/ee/gitlab/event_store.rb
index e11013262fed532f451ca65f05babf060faaf7df..5e1eee8725b13d0cc3fb3c80f61f0e1e42e015cd 100644
--- a/ee/lib/ee/gitlab/event_store.rb
+++ b/ee/lib/ee/gitlab/event_store.rb
@@ -30,6 +30,9 @@ def configure!(store)
           store.subscribe ::MergeRequests::StreamApprovalAuditEventWorker, to: ::MergeRequests::ApprovedEvent
           store.subscribe ::MergeRequests::ProcessApprovalAutoMergeWorker, to: ::MergeRequests::ApprovedEvent
           store.subscribe ::PullMirrors::ReenableConfigurationWorker, to: ::GitlabSubscriptions::RenewedEvent
+          store.subscribe ::Search::ElasticDefaultBranchChangedWorker,
+            to: ::Repositories::DefaultBranchChangedEvent,
+            if: -> (_) { ::Gitlab::CurrentSettings.elasticsearch_indexing? }
         end
       end
     end
diff --git a/ee/spec/lib/ee/gitlab/event_store_spec.rb b/ee/spec/lib/ee/gitlab/event_store_spec.rb
index 0f22c3a9deea91fa542756470323573c12be5f9c..2ac8ec15937f35aad6ee15d768712268ab43ba03 100644
--- a/ee/spec/lib/ee/gitlab/event_store_spec.rb
+++ b/ee/spec/lib/ee/gitlab/event_store_spec.rb
@@ -12,7 +12,8 @@
         ::Ci::PipelineCreatedEvent,
         ::Repositories::KeepAroundRefsCreatedEvent,
         ::MergeRequests::ApprovedEvent,
-        ::GitlabSubscriptions::RenewedEvent
+        ::GitlabSubscriptions::RenewedEvent,
+        ::Repositories::DefaultBranchChangedEvent
       )
     end
   end
diff --git a/ee/spec/workers/search/elastic_default_branch_changed_worker_spec.rb b/ee/spec/workers/search/elastic_default_branch_changed_worker_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..225de71a493bdb653ef650d9fbdcf334f9d91ee0
--- /dev/null
+++ b/ee/spec/workers/search/elastic_default_branch_changed_worker_spec.rb
@@ -0,0 +1,151 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Search::ElasticDefaultBranchChangedWorker, feature_category: :global_search do
+  let_it_be_with_reload(:project) { create(:project, :repository) }
+
+  let(:default_branch_changed_event) { Repositories::DefaultBranchChangedEvent.new(data: data) }
+  let(:container) { project }
+  let(:data) { { container_id: container.id, container_type: container.class.name } }
+
+  before do
+    stub_ee_application_setting(elasticsearch_indexing: true)
+    allow(ElasticCommitIndexerWorker).to receive(:perform_async).and_return(true)
+    allow(ElasticWikiIndexerWorker).to receive(:perform_async).and_return(true)
+  end
+
+  it_behaves_like 'subscribes to event' do
+    let(:event) { default_branch_changed_event }
+  end
+
+  context 'when passed a project' do
+    it 'schedules ElasticCommitIndexerWorker' do
+      expect(ElasticCommitIndexerWorker).to receive(:perform_async).with(project.id)
+
+      consume_event(subscriber: described_class, event: default_branch_changed_event)
+    end
+
+    context 'when project does not exist' do
+      let(:data) { { container_id: non_existing_record_id, container_type: container.class.name } }
+
+      it 'does not schedule ElasticCommitIndexerWorker and does not raise an exception' do
+        expect(ElasticCommitIndexerWorker).not_to receive(:perform_async)
+
+        expect { consume_event(subscriber: described_class, event: default_branch_changed_event) }
+          .not_to raise_exception
+      end
+    end
+
+    context 'when project does not use elasticsearch' do
+      before do
+        stub_ee_application_setting(elasticsearch_limit_indexing: true)
+      end
+
+      it 'does not schedule ElasticCommitIndexerWorker' do
+        expect(ElasticCommitIndexerWorker).not_to receive(:perform_async)
+
+        consume_event(subscriber: described_class, event: default_branch_changed_event)
+      end
+    end
+
+    context 'when elasticsearch_indexing is not enabled' do
+      before do
+        stub_ee_application_setting(elasticsearch_indexing: false)
+      end
+
+      it 'does not schedule ElasticCommitIndexerWorker' do
+        expect(ElasticCommitIndexerWorker).not_to receive(:perform_async)
+
+        consume_event(subscriber: described_class, event: default_branch_changed_event)
+      end
+    end
+  end
+
+  context 'when passed a group wiki' do
+    let_it_be(:group_wiki) { create(:group_wiki) }
+
+    let(:container) { group_wiki }
+
+    before do
+      allow(::Wiki).to receive(:use_separate_indices?).and_return(true)
+    end
+
+    it 'schedules ElasticWikiIndexerWorker' do
+      expect(ElasticWikiIndexerWorker)
+        .to receive(:perform_async).with(group_wiki.group.id, 'Group')
+
+      consume_event(subscriber: described_class, event: default_branch_changed_event)
+    end
+
+    context 'when group does not exist' do
+      let(:data) { { container_id: non_existing_record_id, container_type: container.class.name } }
+
+      it 'does not schedule ElasticWikiIndexerWorker and does not raise an exception' do
+        expect(ElasticWikiIndexerWorker).not_to receive(:perform_async)
+
+        expect { consume_event(subscriber: described_class, event: default_branch_changed_event) }
+          .not_to raise_exception
+      end
+    end
+
+    context 'when group does not use elasticsearch' do
+      before do
+        stub_ee_application_setting(elasticsearch_limit_indexing: true)
+      end
+
+      it 'does not schedule ElasticWikiIndexerWorker' do
+        expect(ElasticWikiIndexerWorker).not_to receive(:perform_async)
+
+        consume_event(subscriber: described_class, event: default_branch_changed_event)
+      end
+    end
+
+    context 'when Wiki.use_separate_indices? is false' do
+      before do
+        allow(::Wiki).to receive(:use_separate_indices?).and_return(false)
+      end
+
+      it 'does not schedule ElasticWikiIndexerWorker' do
+        expect(ElasticWikiIndexerWorker).not_to receive(:perform_async)
+
+        consume_event(subscriber: described_class, event: default_branch_changed_event)
+      end
+    end
+  end
+
+  context 'when passed a project wiki' do
+    let_it_be(:project_wiki) { create(:project_wiki, project: project) }
+
+    let(:container) { project_wiki }
+
+    it 'schedules ElasticWikiIndexerWorker' do
+      expect(ElasticWikiIndexerWorker).to receive(:perform_async).with(project.id, 'Project')
+
+      consume_event(subscriber: described_class, event: default_branch_changed_event)
+    end
+
+    context 'when project wiki does not exist' do
+      let(:data) { { container_id: non_existing_record_id, container_type: container.class.name } }
+
+      it 'does not schedule ElasticWikiIndexerWorker and does not raise an exception' do
+        expect(ElasticWikiIndexerWorker).not_to receive(:perform_async)
+
+        expect { consume_event(subscriber: described_class, event: default_branch_changed_event) }
+          .not_to raise_exception
+      end
+    end
+
+    context 'when project wiki does not use elasticsearch' do
+      before do
+        stub_ee_application_setting(elasticsearch_limit_indexing: true)
+      end
+
+      it 'does not schedule ElasticWikiIndexerWorker' do
+        expect(ElasticWikiIndexerWorker).not_to receive(:perform_async)
+
+        consume_event(subscriber: described_class, event: default_branch_changed_event)
+      end
+    end
+  end
+end
diff --git a/spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb b/spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb
index 0a07c9d677b41d8b396d4e7ed52abaf8e99c6d0b..187c0b3ab43fd2175466320a35d61c34a3864a5c 100644
--- a/spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/has_repository_shared_examples.rb
@@ -162,10 +162,24 @@
   end
 
   describe '#after_repository_change_head' do
+    let(:event) { instance_double('Repositories::DefaultBranchChangedEvent') }
+    let(:event_data) { { container_id: stubbed_container.id, container_type: stubbed_container.class.name } }
+
     it 'calls #reload_default_branch' do
       expect(stubbed_container).to receive(:reload_default_branch)
 
       stubbed_container.after_repository_change_head
     end
+
+    it 'publishes an Repositories::DefaultBranchChangedEvent event' do
+      allow(Repositories::DefaultBranchChangedEvent)
+        .to receive(:new)
+        .with(data: event_data)
+        .and_return(event)
+
+      expect(Gitlab::EventStore).to receive(:publish).with(event).once
+
+      stubbed_container.after_repository_change_head
+    end
   end
 end