diff --git a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/change.rb b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/change.rb
index ce43bd6e0c6acd97ab57ca73ad21e4f9b13d7712..586f64cd76c1930287e9802a13ccc71dbca08e20 100644
--- a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/change.rb
+++ b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/change.rb
@@ -68,14 +68,6 @@ def commit_message
         MARKDOWN
       end
 
-      def matches_filters?(filters)
-        filters.all? do |filter|
-          identifiers.any? do |identifier|
-            identifier.match?(filter)
-          end
-        end
-      end
-
       def update_required?(category)
         !category.in?(non_housekeeper_changes)
       end
diff --git a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/filter_identifiers.rb b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/filter_identifiers.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8db407eb33593bb6a4cd09262781130147232b28
--- /dev/null
+++ b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/filter_identifiers.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module Housekeeper
+    class FilterIdentifiers
+      def initialize(filters)
+        @filters = filters
+      end
+
+      def matches_filters?(identifiers)
+        @filters.all? do |filter|
+          identifiers.any? do |identifier|
+            identifier.match?(filter)
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/keep.rb b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/keep.rb
index d982e3ba9bbe4e622d82618cb83da06d81df0e70..e0609cb8767f7548d726de1a0a256cb1e3ee3e1d 100644
--- a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/keep.rb
+++ b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/keep.rb
@@ -15,8 +15,31 @@ module Housekeeper
     #   )
     #   ```
     class Keep
-      def initialize(logger: nil)
+      attr_reader :filter_identifiers
+
+      def initialize(logger: nil, filter_identifiers: nil)
         @logger = logger || Logger.new(nil)
+        @filter_identifiers = filter_identifiers
+      end
+
+      # This method is used to filter for each change at more granular level. For example:
+      # - When we pass --filter-identifiers my_feature_flag,
+      #   it should only create an MR specifically for my_feature_flag because
+      #   we are having the feature flag name in the change.identifiers
+      # Since the filtering logic is also implemented in the `Runner` class,
+      # it is not required to use this in a keep, but it is recommended for
+      # keeps which have expensive computation to perform. This is because
+      # the Runner only gets the change object after the Keep has finished
+      # computing the change.
+      # This can be done in the `each_change` method like:
+      # ```
+      # next unless matches_filter_identifiers?(change.identifiers)
+      # ... do the computation heavy work and yield change object.
+      # ```
+      def matches_filter_identifiers?(identifiers)
+        return true unless filter_identifiers
+
+        filter_identifiers.matches_filters?(identifiers)
       end
 
       # The each_change method must update local working copy files and yield a Change object which describes the
diff --git a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/runner.rb b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/runner.rb
index 8b587518bc7c0aa8bf4c29bd0cb64451b96cc40d..040842c6b39ab897b31f4149a7defdf2ae5b9961 100644
--- a/gems/gitlab-housekeeper/lib/gitlab/housekeeper/runner.rb
+++ b/gems/gitlab-housekeeper/lib/gitlab/housekeeper/runner.rb
@@ -36,7 +36,7 @@ def initialize(
                    all_keeps
                  end
 
-        @filter_identifiers = filter_identifiers
+        @filter_identifiers = ::Gitlab::Housekeeper::FilterIdentifiers.new(filter_identifiers)
       end
 
       def run
@@ -45,7 +45,7 @@ def run
         git.with_clean_state do
           @keeps.each do |keep_class|
             @logger.puts "Running keep #{keep_class}"
-            keep = keep_class.new(logger: @logger)
+            keep = keep_class.new(logger: @logger, filter_identifiers: @filter_identifiers)
             keep.each_change do |change|
               unless change.valid?
                 @logger.warn "Ignoring invalid change from: #{keep_class}"
@@ -57,7 +57,7 @@ def run
               branch_name = git.create_branch(change)
               add_standard_change_data(change)
 
-              if change.aborted? || !change.matches_filters?(@filter_identifiers)
+              if change.aborted? || !@filter_identifiers.matches_filters?(change.identifiers)
                 # At this point the keep has already run and edited files so we need to
                 # restore the local working copy. We could simply checkout all
                 # changed_files but this is very risky as it could mean losing work that
diff --git a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/change_spec.rb b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/change_spec.rb
index c50b6ab60664def1f694d6c5c3cb4b96f83d4156..dbe515e089042273513acb396e2e9b3716b2ed38 100644
--- a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/change_spec.rb
+++ b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/change_spec.rb
@@ -168,25 +168,4 @@
       end
     end
   end
-
-  describe '#matches_filters?' do
-    let(:identifiers) { %w[this-is a-list of IdentifierS] }
-    let(:change) { create_change(identifiers: identifiers) }
-
-    it 'matches when all regexes match at least one identifier' do
-      expect(change.matches_filters?([/list/, /Ide.*fier/])).to eq(true)
-    end
-
-    it 'does not match when none of the regexes match' do
-      expect(change.matches_filters?([/nomatch/, /Ide.*fffffier/])).to eq(false)
-    end
-
-    it 'does not match when only some of the regexes match' do
-      expect(change.matches_filters?([/nomatch/, /Ide.*fier/])).to eq(false)
-    end
-
-    it 'matches an empty list of filters' do
-      expect(change.matches_filters?([])).to eq(true)
-    end
-  end
 end
diff --git a/gems/gitlab-housekeeper/spec/gitlab/housekeeper/filter_identifiers_spec.rb b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/filter_identifiers_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0c3774f7ae711e8ada79c9157a2d7a6220b92dd5
--- /dev/null
+++ b/gems/gitlab-housekeeper/spec/gitlab/housekeeper/filter_identifiers_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'gitlab/housekeeper/filter_identifiers'
+
+RSpec.describe ::Gitlab::Housekeeper::FilterIdentifiers do
+  describe '.matches_filters?' do
+    let(:identifiers) { %w[this-is a-list of IdentifierS] }
+
+    it 'matches when all regexes match at least one identifier' do
+      filter_identifiers = described_class.new([/list/, /Ide.*fier/])
+      expect(filter_identifiers.matches_filters?(identifiers)).to eq(true)
+    end
+
+    it 'does not match when none of the regexes match' do
+      filter_identifiers = described_class.new([/nomatch/, /Ide.*fffffier/])
+      expect(filter_identifiers.matches_filters?(identifiers)).to eq(false)
+    end
+
+    it 'does not match when only some of the regexes match' do
+      filter_identifiers = described_class.new([/nomatch/, /Ide.*fier/])
+      expect(filter_identifiers.matches_filters?(identifiers)).to eq(false)
+    end
+
+    it 'matches an empty list of filters' do
+      filter_identifiers = described_class.new([])
+      expect(filter_identifiers.matches_filters?(identifiers)).to eq(true)
+    end
+  end
+end