diff --git a/danger/product_intelligence/Dangerfile b/danger/product_intelligence/Dangerfile
index c38d87604cc22563411d10451c1b39732d98f241..1be549f139f18e2d4d1adaba91f8dc0ac755fe5e 100644
--- a/danger/product_intelligence/Dangerfile
+++ b/danger/product_intelligence/Dangerfile
@@ -1,3 +1,5 @@
 # frozen_string_literal: true
 
 product_intelligence.check!
+
+product_intelligence.check_affected_scopes!
diff --git a/spec/tooling/danger/product_intelligence_spec.rb b/spec/tooling/danger/product_intelligence_spec.rb
index ea08e3bc6dbc52b00f30828205cfef9c94aaf8a0..fab8b0c61fa272caf8c290bced882dbc0f2b2885 100644
--- a/spec/tooling/danger/product_intelligence_spec.rb
+++ b/spec/tooling/danger/product_intelligence_spec.rb
@@ -12,12 +12,16 @@
   subject(:product_intelligence) { fake_danger.new(helper: fake_helper) }
 
   let(:fake_danger) { DangerSpecHelper.fake_danger.include(described_class) }
-  let(:changed_files) { ['metrics/counts_7d/test_metric.yml'] }
-  let(:changed_lines) { ['+tier: ee'] }
+  let(:previous_label_to_add) { 'label_to_add' }
+  let(:labels_to_add) { [previous_label_to_add] }
+  let(:ci_env) { true }
+  let(:has_product_intelligence_label) { true }
 
   before do
-    allow(fake_helper).to receive(:all_changed_files).and_return(changed_files)
     allow(fake_helper).to receive(:changed_lines).and_return(changed_lines)
+    allow(fake_helper).to receive(:labels_to_add).and_return(labels_to_add)
+    allow(fake_helper).to receive(:ci?).and_return(ci_env)
+    allow(fake_helper).to receive(:mr_has_labels?).with('product intelligence').and_return(has_product_intelligence_label)
   end
 
   describe '#check!' do
@@ -26,17 +30,13 @@
     let(:markdown_formatted_list) { 'markdown formatted list' }
     let(:review_pending_label) { 'product intelligence::review pending' }
     let(:approved_label) { 'product intelligence::approved' }
-    let(:ci_env) { true }
-    let(:previous_label_to_add) { 'label_to_add' }
-    let(:labels_to_add) { [previous_label_to_add] }
-    let(:has_product_intelligence_label) { true }
+    let(:changed_files) { ['metrics/counts_7d/test_metric.yml'] }
+    let(:changed_lines) { ['+tier: ee'] }
 
     before do
+      allow(fake_helper).to receive(:all_changed_files).and_return(changed_files)
       allow(fake_helper).to receive(:changes_by_category).and_return(product_intelligence: changed_files, database: ['other_files.yml'])
-      allow(fake_helper).to receive(:ci?).and_return(ci_env)
-      allow(fake_helper).to receive(:mr_has_labels?).with('product intelligence').and_return(has_product_intelligence_label)
       allow(fake_helper).to receive(:markdown_list).with(changed_files).and_return(markdown_formatted_list)
-      allow(fake_helper).to receive(:labels_to_add).and_return(labels_to_add)
     end
 
     shared_examples "doesn't add new labels" do
@@ -121,4 +121,58 @@
       end
     end
   end
+
+  describe '#check_affected_scopes!' do
+    let(:fixture_dir_glob) { Dir.glob(File.join('spec', 'tooling', 'fixtures', 'metrics', '*.rb')) }
+    let(:changed_lines) { ['+  scope :active, -> { iwhere(email: Array(emails)) }'] }
+
+    before do
+      allow(Dir).to receive(:glob).and_return(fixture_dir_glob)
+      allow(fake_helper).to receive(:markdown_list).with({ 'active' => fixture_dir_glob }).and_return('a')
+    end
+
+    context 'when a model was modified' do
+      let(:modified_files) { ['app/models/super_user.rb'] }
+
+      context 'when a scope is changed' do
+        context 'and a metrics uses the affected scope' do
+          it 'producing warning' do
+            expect(product_intelligence).to receive(:warn).with(%r{#{modified_files}})
+
+            product_intelligence.check_affected_scopes!
+          end
+        end
+
+        context 'when no metrics using the affected scope' do
+          let(:changed_lines) { ['+scope :foo, -> { iwhere(email: Array(emails)) }'] }
+
+          it 'doesnt do anything' do
+            expect(product_intelligence).not_to receive(:warn)
+
+            product_intelligence.check_affected_scopes!
+          end
+        end
+      end
+    end
+
+    context 'when an unrelated model with matching scope was modified' do
+      let(:modified_files) { ['app/models/post_box.rb'] }
+
+      it 'doesnt do anything' do
+        expect(product_intelligence).not_to receive(:warn)
+
+        product_intelligence.check_affected_scopes!
+      end
+    end
+
+    context 'when models arent modified' do
+      let(:modified_files) { ['spec/app/models/user_spec.rb'] }
+
+      it 'doesnt do anything' do
+        expect(product_intelligence).not_to receive(:warn)
+
+        product_intelligence.check_affected_scopes!
+      end
+    end
+  end
 end
diff --git a/spec/tooling/fixtures/metrics/sample_instrumentation_metric.rb b/spec/tooling/fixtures/metrics/sample_instrumentation_metric.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d6b86137b1b555c90eaf74a4a394282ad4493f11
--- /dev/null
+++ b/spec/tooling/fixtures/metrics/sample_instrumentation_metric.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module Usage
+    module Metrics
+      module Instrumentations
+        class ActiveUserCountMetric < DatabaseMetric
+          operation :count
+
+          relation { SuperUser.active }
+        end
+      end
+    end
+  end
+end
diff --git a/tooling/danger/product_intelligence.rb b/tooling/danger/product_intelligence.rb
index 621a7b509b0cfac883ca1104a0926668c04716e2..58e327408a1262f3ba0d1e6adc80b073b37b1cc7 100644
--- a/tooling/danger/product_intelligence.rb
+++ b/tooling/danger/product_intelligence.rb
@@ -4,15 +4,21 @@
 module Tooling
   module Danger
     module ProductIntelligence
+      METRIC_DIRS = %w[lib/gitlab/usage/metrics/instrumentations ee/lib/gitlab/usage/metrics/instrumentations].freeze
       APPROVED_LABEL = 'product intelligence::approved'
       REVIEW_LABEL = 'product intelligence::review pending'
       CHANGED_FILES_MESSAGE = <<~MSG
-      For the following files, a review from the [Data team and Product Intelligence team](https://gitlab.com/groups/gitlab-org/analytics-section/product-intelligence/engineers/-/group_members?with_inherited_permissions=exclude) is recommended
-      Please check the ~"product intelligence" [Service Ping guide](https://docs.gitlab.com/ee/development/service_ping/) or the [Snowplow guide](https://docs.gitlab.com/ee/development/snowplow/).
+        For the following files, a review from the [Data team and Product Intelligence team](https://gitlab.com/groups/gitlab-org/analytics-section/product-intelligence/engineers/-/group_members?with_inherited_permissions=exclude) is recommended
+        Please check the ~"product intelligence" [Service Ping guide](https://docs.gitlab.com/ee/development/service_ping/) or the [Snowplow guide](https://docs.gitlab.com/ee/development/snowplow/).
 
-      For MR review guidelines, see the [Service Ping review guidelines](https://docs.gitlab.com/ee/development/service_ping/review_guidelines.html) or the [Snowplow review guidelines](https://docs.gitlab.com/ee/development/snowplow/review_guidelines.html).
+        For MR review guidelines, see the [Service Ping review guidelines](https://docs.gitlab.com/ee/development/service_ping/review_guidelines.html) or the [Snowplow review guidelines](https://docs.gitlab.com/ee/development/snowplow/review_guidelines.html).
 
-      %<changed_files>s
+        %<changed_files>s
+
+      MSG
+
+      CHANGED_SCOPE_MESSAGE = <<~MSG
+        The following metrics could be affected by the modified scopes and require ~"product intelligence" review:
 
       MSG
 
@@ -33,8 +39,61 @@ def check!
         helper.labels_to_add.concat(labels_to_add) unless labels_to_add.empty?
       end
 
+      def check_affected_scopes!
+        metric_scope_list = metric_scope_affected
+        return if metric_scope_list.empty?
+
+        warn CHANGED_SCOPE_MESSAGE + convert_to_table(metric_scope_list)
+        helper.labels_to_add.concat(missing_labels) unless missing_labels.empty?
+      end
+
       private
 
+      def convert_to_table(items)
+        message = "Scope | Affected files |\n"
+        message += "--- | ----- |\n"
+        items.each_key do |scope|
+          affected_files = items[scope]
+          message += "`#{scope}`| `#{affected_files[0]}` |\n"
+          affected_files[1..]&.each do |file_name|
+            message += " | `#{file_name}` |\n"
+          end
+        end
+        message
+      end
+
+      def metric_scope_affected
+        select_models(helper.modified_files).each_with_object(Hash.new { |h, k| h[k] = [] }) do |file_name, matched_files|
+          helper.changed_lines(file_name).each do |mod_line, _i|
+            next unless mod_line =~ /^\+\s+scope :\w+/
+
+            affected_scope = mod_line.match(/:\w+/)
+            next if affected_scope.nil?
+
+            affected_class = File.basename(file_name, '.rb').split('_').map(&:capitalize).join
+            scope_name = "#{affected_class}.#{affected_scope[0][1..]}"
+
+            each_metric do |metric_def|
+              next unless File.read(metric_def).include?("relation { #{scope_name}")
+
+              matched_files[scope_name].push(metric_def)
+            end
+          end
+        end
+      end
+
+      def select_models(files)
+        files.select do |f|
+          f.start_with?('app/models/', 'ee/app/models/')
+        end
+      end
+
+      def each_metric(&block)
+        METRIC_DIRS.each do |dir|
+          Dir.glob(File.join(dir, '*.rb')).each(&block)
+        end
+      end
+
       def missing_labels
         return [] unless helper.ci?