diff --git a/app/graphql/resolvers/ci/jobs_resolver.rb b/app/graphql/resolvers/ci/jobs_resolver.rb
index df138a155388bdd665f2e24524879237879beaa5..91f29948ad086801063298579f3ba9f9a401d6d3 100644
--- a/app/graphql/resolvers/ci/jobs_resolver.rb
+++ b/app/graphql/resolvers/ci/jobs_resolver.rb
@@ -15,9 +15,15 @@ class JobsResolver < BaseResolver
               required: false,
               description: 'Filter jobs by status.'
 
-      def resolve(statuses: nil, security_report_types: [])
+      argument :retried, ::GraphQL::Types::Boolean,
+              required: false,
+              description: 'Filter jobs by retry-status.'
+
+      def resolve(statuses: nil, security_report_types: [], retried: nil)
         jobs = init_collection(security_report_types)
         jobs = jobs.with_status(statuses) if statuses.present?
+        jobs = jobs.retried if retried
+        jobs = jobs.latest if retried == false
 
         jobs
       end
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index b20a671179b2df93cd4b3c80db88065fa236cc8e..802cb09b36a7f3cfac3ff00c6ce970f7af04f144 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -78,6 +78,8 @@ class JobType < BaseObject
             description: 'Ref name of the job.'
       field :ref_path, GraphQL::Types::String, null: true,
             description: 'Path to the ref.'
+      field :retried, GraphQL::Types::Boolean, null: true,
+            description: 'Indicates that the job has been retried.'
       field :retryable, GraphQL::Types::Boolean, null: false, method: :retryable?,
             description: 'Indicates the job can be retried.'
       field :scheduling_type, GraphQL::Types::String, null: true,
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 90894506cfda84649cd4c97839ac7a6359ba4f1b..32c34b176c157e55b8cf61e7e153e207becf0cc3 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -9924,6 +9924,7 @@ Represents the total number of issues and their weights for a particular day.
 | <a id="cijobqueuedduration"></a>`queuedDuration` | [`Duration`](#duration) | How long the job was enqueued before starting. |
 | <a id="cijobrefname"></a>`refName` | [`String`](#string) | Ref name of the job. |
 | <a id="cijobrefpath"></a>`refPath` | [`String`](#string) | Path to the ref. |
+| <a id="cijobretried"></a>`retried` | [`Boolean`](#boolean) | Indicates that the job has been retried. |
 | <a id="cijobretryable"></a>`retryable` | [`Boolean!`](#boolean) | Indicates the job can be retried. |
 | <a id="cijobscheduledat"></a>`scheduledAt` | [`Time`](#time) | Schedule for the build. |
 | <a id="cijobschedulingtype"></a>`schedulingType` | [`String`](#string) | Type of job scheduling. Value is `dag` if the job uses the `needs` keyword, and `stage` otherwise. |
@@ -14972,6 +14973,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
 
 | Name | Type | Description |
 | ---- | ---- | ----------- |
+| <a id="pipelinejobsretried"></a>`retried` | [`Boolean`](#boolean) | Filter jobs by retry-status. |
 | <a id="pipelinejobssecurityreporttypes"></a>`securityReportTypes` | [`[SecurityReportTypeEnum!]`](#securityreporttypeenum) | Filter jobs by the type of security report they produce. |
 | <a id="pipelinejobsstatuses"></a>`statuses` | [`[CiJobStatus!]`](#cijobstatus) | Filter jobs by status. |
 
diff --git a/ee/spec/requests/api/graphql/boards/board_lists_query_spec.rb b/ee/spec/requests/api/graphql/boards/board_lists_query_spec.rb
index 90c6efe7cc98814713927b2c80ceca899a359d10..12aa1d903064fbb9b7efa7896ca575e515760d0c 100644
--- a/ee/spec/requests/api/graphql/boards/board_lists_query_spec.rb
+++ b/ee/spec/requests/api/graphql/boards/board_lists_query_spec.rb
@@ -90,7 +90,8 @@ def pagination_query(params)
 
           context 'when ascending' do
             it_behaves_like 'sorted paginated query' do
-              let(:sort_param) { }
+              include_context 'no sort argument'
+
               let(:first_param) { 2 }
               let(:all_records) { lists.map { |list| global_id_of(list).to_s } }
             end
diff --git a/ee/spec/requests/api/graphql/boards/epic_board_list_epics_query_spec.rb b/ee/spec/requests/api/graphql/boards/epic_board_list_epics_query_spec.rb
index e9071cc6e88c7f193995ecf300201034791c0854..eeb85fbf50bd90d3f84aa6ff0053c4ba7cd3dc6a 100644
--- a/ee/spec/requests/api/graphql/boards/epic_board_list_epics_query_spec.rb
+++ b/ee/spec/requests/api/graphql/boards/epic_board_list_epics_query_spec.rb
@@ -46,9 +46,8 @@ def pagination_query(params = {})
     let(:all_records) { [epic2.to_global_id.to_s, epic1.to_global_id.to_s, epic3.to_global_id.to_s] }
 
     it_behaves_like 'sorted paginated query' do
-      # currently we don't support custom sorting for epic lists,
-      # nil value will be ignored by ::Graphql::Arguments
-      let(:sort_param) { nil }
+      include_context 'no sort argument'
+
       let(:first_param) { 2 }
     end
   end
diff --git a/ee/spec/requests/api/graphql/boards/epic_boards_query_spec.rb b/ee/spec/requests/api/graphql/boards/epic_boards_query_spec.rb
index 07b14627b538bd55d6c3523dd7150d82f577cb3b..b9096ba04166a15b5248918698e71c568773ed44 100644
--- a/ee/spec/requests/api/graphql/boards/epic_boards_query_spec.rb
+++ b/ee/spec/requests/api/graphql/boards/epic_boards_query_spec.rb
@@ -43,9 +43,8 @@ def pagination_results_data(nodes)
       end
 
       it_behaves_like 'sorted paginated query' do
-        # currently we don't support custom sorting for epic boards,
-        # nil value will be ignored by ::Graphql::Arguments
-        let(:sort_param) { nil }
+        include_context 'no sort argument'
+
         let(:first_param) { 2 }
       end
     end
diff --git a/ee/spec/requests/api/graphql/boards/epic_lists_query_spec.rb b/ee/spec/requests/api/graphql/boards/epic_lists_query_spec.rb
index 5e78c6713d4111b3efd993c83bc5e9aaad3ec838..fcd362ccf412eff3a2a1f5dcf5763c8a4f653352 100644
--- a/ee/spec/requests/api/graphql/boards/epic_lists_query_spec.rb
+++ b/ee/spec/requests/api/graphql/boards/epic_lists_query_spec.rb
@@ -51,9 +51,8 @@ def pagination_results_data(nodes)
       end
 
       it_behaves_like 'sorted paginated query' do
-        # currently we don't support custom sorting for epic lists,
-        # nil value will be ignored by ::Graphql::Arguments
-        let(:sort_param) { nil }
+        include_context 'no sort argument'
+
         let(:first_param) { 2 }
       end
     end
diff --git a/ee/spec/requests/api/graphql/group/epic/epic_issues_spec.rb b/ee/spec/requests/api/graphql/group/epic/epic_issues_spec.rb
index 450c22e30f6867486d7395a9f495aa1dceaadb8e..71df5b2de946c41db47ae4f1bb1a2a7d8d8f25a6 100644
--- a/ee/spec/requests/api/graphql/group/epic/epic_issues_spec.rb
+++ b/ee/spec/requests/api/graphql/group/epic/epic_issues_spec.rb
@@ -86,8 +86,9 @@ def epic_fields(args)
         end
 
         it_behaves_like 'sorted paginated query' do
+          include_context 'no sort argument'
+
           let(:current_user) { user }
-          let(:sort_param) { }
           let(:first_param) { 1 }
           let(:all_records) { [issue, confidential_issue].map { |i| global_id_of(i).to_s } }
         end
diff --git a/ee/spec/requests/api/graphql/group_query_spec.rb b/ee/spec/requests/api/graphql/group_query_spec.rb
index 68bbf3e64dba90a54928a902364f32c81bb82c20..08213623da05e97e1b4fce91eedddc3b69731513 100644
--- a/ee/spec/requests/api/graphql/group_query_spec.rb
+++ b/ee/spec/requests/api/graphql/group_query_spec.rb
@@ -364,8 +364,9 @@ def pagination_query(params)
       let(:start_date) { 5.weeks.ago.to_date.to_s }
 
       it_behaves_like 'sorted paginated query' do
+        include_context 'no sort argument'
+
         let(:node_path) { ['averageCoverage'] }
-        let(:sort_param) { }
         let(:first_param) { 2 }
         let(:all_records) { [cov_1, cov_2, cov_3, cov_4, cov_5].reverse.map(&:coverage) }
       end
diff --git a/ee/spec/requests/api/graphql/project/dast_profiles_spec.rb b/ee/spec/requests/api/graphql/project/dast_profiles_spec.rb
index 772ff7d037e5f82bf6c4d8c353ed0b1b1e5a90a1..35614540a996cf96cc570536ca33444fb6b715a0 100644
--- a/ee/spec/requests/api/graphql/project/dast_profiles_spec.rb
+++ b/ee/spec/requests/api/graphql/project/dast_profiles_spec.rb
@@ -83,7 +83,8 @@ def pagination_results_data(dast_profiles)
     end
 
     it_behaves_like 'sorted paginated query' do
-      let(:sort_param) { nil }
+      include_context 'no sort argument'
+
       let(:first_param) { 3 }
     end
 
diff --git a/ee/spec/requests/api/graphql/project/dast_site_validations_spec.rb b/ee/spec/requests/api/graphql/project/dast_site_validations_spec.rb
index 1be1aadc3c79155a14636039164ef3724957e6b0..31b7aa03a87b6df27ce06673f56880c527074fab 100644
--- a/ee/spec/requests/api/graphql/project/dast_site_validations_spec.rb
+++ b/ee/spec/requests/api/graphql/project/dast_site_validations_spec.rb
@@ -70,7 +70,8 @@ def pagination_results_data(dast_site_validations)
     end
 
     it_behaves_like 'sorted paginated query' do
-      let(:sort_param) { nil }
+      include_context 'no sort argument'
+
       let(:first_param) { 3 }
 
       let(:all_records) do
diff --git a/spec/graphql/types/ci/job_type_spec.rb b/spec/graphql/types/ci/job_type_spec.rb
index 655c36368832b9d581ea8f548c8fc7662ac84611..959f0ebefd8c75166645ab49d1a2af23975b9bff 100644
--- a/spec/graphql/types/ci/job_type_spec.rb
+++ b/spec/graphql/types/ci/job_type_spec.rb
@@ -33,6 +33,7 @@
       refName
       refPath
       retryable
+      retried
       scheduledAt
       schedulingType
       shortSha
diff --git a/spec/requests/api/graphql/boards/board_lists_query_spec.rb b/spec/requests/api/graphql/boards/board_lists_query_spec.rb
index eb206465bce5c5129f8e4e9e50da5c6b9151673f..39ff108a9e1d4f4a4ba5c04494e4fe37553c4a48 100644
--- a/spec/requests/api/graphql/boards/board_lists_query_spec.rb
+++ b/spec/requests/api/graphql/boards/board_lists_query_spec.rb
@@ -96,7 +96,8 @@ def pagination_query(params)
 
           context 'when ascending' do
             it_behaves_like 'sorted paginated query' do
-              let(:sort_param) { }
+              include_context 'no sort argument'
+
               let(:first_param) { 2 }
               let(:all_records) { lists.map { |list| a_graphql_entity_for(list) } }
             end
diff --git a/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
index 9bb661a734e5f953f201bf3d17a073c8b56a1401..37ef7089c2f2f1d49b0ab2b046190784033ade7b 100644
--- a/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
+++ b/spec/requests/api/graphql/group/dependency_proxy_manifests_spec.rb
@@ -125,7 +125,8 @@
       let_it_be(:descending_manifests) { manifests.reverse.map { |manifest| global_id_of(manifest) } }
 
       it_behaves_like 'sorted paginated query' do
-        let(:sort_param) { '' }
+        include_context 'no sort argument'
+
         let(:first_param) { 2 }
         let(:all_records) { descending_manifests.map(&:to_s) }
       end
@@ -134,7 +135,7 @@
     def pagination_query(params)
       # remove sort since the type does not accept sorting, but be future proof
       graphql_query_for('group', { 'fullPath' => group.full_path },
-        query_nodes(:dependencyProxyManifests, :id, include_pagination_info: true, args: params.merge(sort: nil))
+        query_nodes(:dependencyProxyManifests, :id, include_pagination_info: true, args: params)
       )
     end
   end
diff --git a/spec/requests/api/graphql/project/pipeline_spec.rb b/spec/requests/api/graphql/project/pipeline_spec.rb
index 1151438b446c2821c80dfad7655d6ea865ce51bc..08c6a2d9927ca5f8fd4735cb59a0fb4272259bff 100644
--- a/spec/requests/api/graphql/project/pipeline_spec.rb
+++ b/spec/requests/api/graphql/project/pipeline_spec.rb
@@ -105,6 +105,62 @@ def successful_pipeline
     end
   end
 
+  context 'when a job has been retried' do
+    let_it_be(:retried) do
+      create(:ci_build, :retried,
+             name: build_job.name,
+             pipeline: pipeline,
+             stage_idx: 0,
+             stage: build_job.stage)
+    end
+
+    let(:fields) do
+      query_graphql_field(:jobs, { retried: retried_argument },
+                          query_graphql_field(:nodes, {}, all_graphql_fields_for('CiJob', max_depth: 3)))
+    end
+
+    context 'when we filter out retried jobs' do
+      let(:retried_argument) { false }
+
+      it 'contains latest jobs' do
+        post_graphql(query, current_user: current_user)
+
+        expect(graphql_data_at(*path, :jobs, :nodes)).to include(
+          a_graphql_entity_for(build_job, :name, :duration, :retried)
+        )
+
+        expect(graphql_data_at(*path, :jobs, :nodes)).not_to include(
+          a_graphql_entity_for(retried)
+        )
+      end
+    end
+
+    context 'when we filter to only retried jobs' do
+      let(:retried_argument) { true }
+
+      it 'contains only retried jobs' do
+        post_graphql(query, current_user: current_user)
+
+        expect(graphql_data_at(*path, :jobs, :nodes)).to contain_exactly(
+          a_graphql_entity_for(retried)
+        )
+      end
+    end
+
+    context 'when we pass null explicitly' do
+      let(:retried_argument) { nil }
+
+      it 'contains all jobs' do
+        post_graphql(query, current_user: current_user)
+
+        expect(graphql_data_at(*path, :jobs, :nodes)).to include(
+          a_graphql_entity_for(build_job),
+          a_graphql_entity_for(retried)
+        )
+      end
+    end
+  end
+
   context 'when requesting only builds with certain statuses' do
     let(:variables) do
       {
diff --git a/spec/support/graphql/arguments.rb b/spec/support/graphql/arguments.rb
index a5bb01c31a3cf76cc5185bbd0c2570ba237588a8..478a460a0f60c0c31e6cc31ddfeb2f7abbdf55a4 100644
--- a/spec/support/graphql/arguments.rb
+++ b/spec/support/graphql/arguments.rb
@@ -5,7 +5,7 @@ class Arguments
     delegate :blank?, :empty?, to: :to_h
 
     def initialize(values)
-      @values = values.compact
+      @values = values
     end
 
     def to_h
@@ -42,7 +42,7 @@ def self.as_graphql_literal(value)
       when Integer, Float, Symbol then value.to_s
       when String, GlobalID then "\"#{value.to_s.gsub(/"/, '\\"')}\""
       when Time, Date then "\"#{value.iso8601}\""
-      when nil then 'null'
+      when NilClass then 'null'
       when true then 'true'
       when false then 'false'
       else
diff --git a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
index 6d6e7b761f6c893753e3c53a1f81e16cf250329d..59927fa1cc9d952591478cf9a4da651076131455 100644
--- a/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/sorted_paginated_query_shared_examples.rb
@@ -44,19 +44,25 @@
 #         end
 #       end
 #
+
+# Include this context if your field does not accept a sort argument
+RSpec.shared_context 'no sort argument' do
+  let(:sort_argument) { graphql_args }
+end
+
 RSpec.shared_examples 'sorted paginated query' do |conditions = {}|
   # Provided as a convenience when constructing queries using string concatenation
   let(:page_info) { 'pageInfo { startCursor endCursor }' }
   # Convenience for using default implementation of pagination_results_data
   let(:node_path) { ['id'] }
+  let(:sort_argument) { graphql_args(sort: sort_param) }
 
   it_behaves_like 'requires variables' do
-    let(:required_variables) { [:sort_param, :first_param, :all_records, :data_path, :current_user] }
+    let(:required_variables) { [:first_param, :all_records, :data_path, :current_user] }
   end
 
   describe do
-    let(:sort_argument)  { graphql_args(sort: sort_param) }
-    let(:params)         { sort_argument }
+    let(:params) { sort_argument }
 
     # Convenience helper for the large number of queries defined as a projection
     # from some root value indexed by full_path to a collection of objects with IID
diff --git a/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb
index e534a02e56298341cd19f832c0b8867dba1e62f0..8ab820e9d43b14c99581eed4a8776a2c29ab7d80 100644
--- a/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/group_and_project_boards_query_shared_examples.rb
@@ -64,7 +64,8 @@ def pagination_query(params)
 
         context 'when ascending' do
           it_behaves_like 'sorted paginated query' do
-            let(:sort_param) { }
+            include_context 'no sort argument'
+
             let(:first_param) { 2 }
 
             def pagination_results_data(nodes)
diff --git a/spec/support_specs/graphql/arguments_spec.rb b/spec/support_specs/graphql/arguments_spec.rb
index ffb58503a0e3d45b8c8c97d619e6c54dbdfe3939..925af1ab79c27cee94fcba725ef9166d6c04a5df 100644
--- a/spec/support_specs/graphql/arguments_spec.rb
+++ b/spec/support_specs/graphql/arguments_spec.rb
@@ -52,7 +52,7 @@
       float: 2.7,
       string: %q[he said "no"],
       enum: :OFF,
-      null: nil, # we expect this to be omitted - absence is the same as explicit nullness
+      null: nil,
       bool_true: true,
       bool_false: false,
       var: ::Graphql::Var.new('x', 'Int')
@@ -64,6 +64,7 @@
       'int: 42, float: 2.7',
       %q(string: "he said \\"no\\""),
       'enum: OFF',
+      'null: null',
       'boolTrue: true, boolFalse: false',
       'var: $x'
     ].join(', '))
diff --git a/spec/support_specs/helpers/graphql_helpers_spec.rb b/spec/support_specs/helpers/graphql_helpers_spec.rb
index f567097af6fe7ea0d01ba20a653643620a882454..c02e4adf983e57842d264f9639200195f2d95ef1 100644
--- a/spec/support_specs/helpers/graphql_helpers_spec.rb
+++ b/spec/support_specs/helpers/graphql_helpers_spec.rb
@@ -305,6 +305,7 @@ def norm(query)
       aFloat: 0.1,
       aString: "wibble",
       anEnum: LOW,
+      null: null,
       aBool: false,
       aVar: #{x.to_graphql_value}
       EXP