diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb
index 18be2aec2e27cf092dd3eac2cb971b63dcc7e9d9..66b16e875c128fa69d558cd7d3a31f7fa159156c 100644
--- a/app/finders/ci/runners_finder.rb
+++ b/app/finders/ci/runners_finder.rb
@@ -29,6 +29,7 @@ def execute
       items = by_runner_type(items)
       items = by_tag_list(items)
       items = by_creator_id(items)
+      items = by_creator_username(items)
       items = by_version_prefix(items)
       items = request_tag_list(items)
 
@@ -130,6 +131,16 @@ def by_creator_id(items)
       items.with_creator_id(creator_id)
     end
 
+    def by_creator_username(items)
+      creator_username = @params[:creator_username].presence
+      return items unless creator_username
+
+      creator_id = User.find_by_username(creator_username)&.id
+      return Ci::Runner.none unless creator_id
+
+      items.with_creator_id(creator_id)
+    end
+
     def by_version_prefix(items)
       sanitized_prefix = @params.fetch(:version_prefix, '')[/^[\d+.]+/]
       return items unless sanitized_prefix
diff --git a/app/graphql/resolvers/ci/runners_resolver.rb b/app/graphql/resolvers/ci/runners_resolver.rb
index 38d2ebe046badf158550951b5bcd234a1467ae75..a289bee9806151bdd4e69ad30beb2cc50832d656 100644
--- a/app/graphql/resolvers/ci/runners_resolver.rb
+++ b/app/graphql/resolvers/ci/runners_resolver.rb
@@ -45,6 +45,11 @@ class RunnersResolver < BaseResolver
                required: false,
                description: 'Filter runners by creator ID.'
 
+      argument :creator_username, GraphQL::Types::String,
+               required: false,
+               description: 'Filter runners by creator username.',
+               alpha: { milestone: '16.7' }
+
       argument :version_prefix, GraphQL::Types::String,
                required: false,
                description: "Filter runners by version. Runners that contain runner managers with the version at " \
@@ -81,6 +86,7 @@ def runners_finder_params(params)
           sort: params[:sort]&.to_s,
           creator_id:
             params[:creator_id] ? ::GitlabSchema.parse_gid(params[:creator_id], expected_type: ::User).model_id : nil,
+          creator_username: params[:creator_username],
           version_prefix: params[:version_prefix],
           preload: {} # we'll handle preloading ourselves
         }.compact
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 37515ddce91d8cd3088d9a6904ec603296a50b0b..f5198c54136a95f5ea4c0888cf110a851e9419b4 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -820,6 +820,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
 | ---- | ---- | ----------- |
 | <a id="queryrunnersactive"></a>`active` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in 14.8. This was renamed. Use: `paused`. |
 | <a id="queryrunnerscreatorid"></a>`creatorId` | [`UserID`](#userid) | Filter runners by creator ID. |
+| <a id="queryrunnerscreatorusername"></a>`creatorUsername` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.7. This feature is an Experiment. It can be changed or removed at any time. Filter runners by creator username. |
 | <a id="queryrunnerspaused"></a>`paused` | [`Boolean`](#boolean) | Filter runners by `paused` (true) or `active` (false) status. |
 | <a id="queryrunnerssearch"></a>`search` | [`String`](#string) | Filter by full token or partial text in description field. |
 | <a id="queryrunnerssort"></a>`sort` | [`CiRunnerSort`](#cirunnersort) | Sort order of results. |
@@ -20313,6 +20314,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
 | ---- | ---- | ----------- |
 | <a id="grouprunnersactive"></a>`active` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in 14.8. This was renamed. Use: `paused`. |
 | <a id="grouprunnerscreatorid"></a>`creatorId` | [`UserID`](#userid) | Filter runners by creator ID. |
+| <a id="grouprunnerscreatorusername"></a>`creatorUsername` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.7. This feature is an Experiment. It can be changed or removed at any time. Filter runners by creator username. |
 | <a id="grouprunnersmembership"></a>`membership` | [`CiRunnerMembershipFilter`](#cirunnermembershipfilter) | Control which runners to include in the results. |
 | <a id="grouprunnerspaused"></a>`paused` | [`Boolean`](#boolean) | Filter runners by `paused` (true) or `active` (false) status. |
 | <a id="grouprunnerssearch"></a>`search` | [`String`](#string) | Filter by full token or partial text in description field. |
@@ -25651,6 +25653,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
 | ---- | ---- | ----------- |
 | <a id="projectrunnersactive"></a>`active` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in 14.8. This was renamed. Use: `paused`. |
 | <a id="projectrunnerscreatorid"></a>`creatorId` | [`UserID`](#userid) | Filter runners by creator ID. |
+| <a id="projectrunnerscreatorusername"></a>`creatorUsername` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.7. This feature is an Experiment. It can be changed or removed at any time. Filter runners by creator username. |
 | <a id="projectrunnerspaused"></a>`paused` | [`Boolean`](#boolean) | Filter runners by `paused` (true) or `active` (false) status. |
 | <a id="projectrunnerssearch"></a>`search` | [`String`](#string) | Filter by full token or partial text in description field. |
 | <a id="projectrunnerssort"></a>`sort` | [`CiRunnerSort`](#cirunnersort) | Sort order of results. |
diff --git a/spec/finders/ci/runners_finder_spec.rb b/spec/finders/ci/runners_finder_spec.rb
index 7e9ef2139c997f0dc986b84caa2ac1f538325648..b1252b53127b41a51f7810ac2fdaf93532f7c8d6 100644
--- a/spec/finders/ci/runners_finder_spec.rb
+++ b/spec/finders/ci/runners_finder_spec.rb
@@ -153,7 +153,7 @@ def execute
             end
           end
 
-          context 'by creator' do
+          context 'by creator id' do
             it 'calls the corresponding scope on Ci::Runner' do
               expect(Ci::Runner).to receive(:with_creator_id).with('1').and_call_original
 
@@ -161,6 +161,24 @@ def execute
             end
           end
 
+          context 'by creator username' do
+            let_it_be(:admin_runner) { create(:ci_runner, creator: admin) }
+
+            it 'calls the corresponding scope on Ci::Runner' do
+              expect(Ci::Runner).to receive(:with_creator_id).with(admin.id).and_call_original
+
+              result = described_class.new(current_user: admin, params: { creator_username: admin.username }).execute
+              expect(result).to match_array [admin_runner]
+            end
+
+            it 'does not call the scope when the username is not found and is empty' do
+              expect(Ci::Runner).not_to receive(:with_creator_id)
+
+              result = described_class.new(current_user: admin, params: { creator_username: "not a username" }).execute
+              expect(result).to be_empty
+            end
+          end
+
           context 'by version' do
             it 'calls the corresponding scope on Ci::Runner' do
               expect(Ci::Runner).to receive(:with_version_prefix).with('15.').and_call_original
diff --git a/spec/graphql/resolvers/ci/runners_resolver_spec.rb b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
index a0239a6ff344f556bf0b399a77653b353099b73b..f59b0ccf8b0605d176d98181c27847c3921cd5c5 100644
--- a/spec/graphql/resolvers/ci/runners_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/runners_resolver_spec.rb
@@ -87,6 +87,7 @@
             search: 'abc',
             sort: :contacted_asc,
             creator_id: 'gid://gitlab/User/1',
+            creator_username: 'root',
             version_prefix: '15.'
           }
         end
@@ -102,6 +103,7 @@
             search: 'abc',
             sort: 'contacted_asc',
             creator_id: '1',
+            creator_username: 'root',
             version_prefix: '15.'
           }
         end
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index d4f7db3bddd814d4d289dcbae29975e32d3b3348..59f69013b377d0055a5f28b1d37c04635099d05a 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -525,16 +525,17 @@
   end
 
   describe '.with_creator_id' do
-    subject { described_class.with_creator_id('1') }
+    let_it_be(:admin) { create(:admin, username: 'root') }
+    let_it_be(:user2) { create(:user, username: 'user2') }
 
-    let_it_be(:runner1) { create(:ci_runner, creator_id: 2) }
-    let_it_be(:runner2) { create(:ci_runner, creator_id: 1) }
-    let_it_be(:runner3) { create(:ci_runner, creator_id: 1) }
-    let_it_be(:runner4) { create(:ci_runner, creator_id: nil) }
+    let_it_be(:user_runner1) { create(:ci_runner, creator: user2) }
+    let_it_be(:admin_runner1) { create(:ci_runner, creator: admin) }
+    let_it_be(:admin_runner2) { create(:ci_runner, creator: admin) }
+    let_it_be(:runner_without_creator) { create(:ci_runner, creator: nil) }
 
-    it "returns runners with creator_id '1'" do
-      is_expected.to contain_exactly(runner2, runner3)
-    end
+    subject { described_class.with_creator_id(admin.id.to_s) }
+
+    it { is_expected.to contain_exactly(admin_runner1, admin_runner2) }
   end
 
   describe '.with_version_prefix' do