diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md
index 121f5e3cbfeb5206b021f5d48746538105d4dd2e..38f1a4e58bcf8f683c1ac4069b4949ffedd65881 100644
--- a/doc/api/graphql/reference/_index.md
+++ b/doc/api/graphql/reference/_index.md
@@ -25329,6 +25329,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodecisecurefileregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodecisecurefileregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodecisecurefileregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodecisecurefileregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodecisecurefileregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.containerRepositoryRegistries`
@@ -25348,6 +25349,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodecontainerrepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodecontainerrepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodecontainerrepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodecontainerrepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodecontainerrepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.dependencyProxyBlobRegistries`
@@ -25371,6 +25373,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodedependencyproxyblobregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodedependencyproxyblobregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodedependencyproxyblobregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodedependencyproxyblobregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodedependencyproxyblobregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.dependencyProxyManifestRegistries`
@@ -25390,6 +25393,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodedependencyproxymanifestregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodedependencyproxymanifestregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodedependencyproxymanifestregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodedependencyproxymanifestregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodedependencyproxymanifestregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.designManagementRepositoryRegistries`
@@ -25413,6 +25417,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodedesignmanagementrepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodedesignmanagementrepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodedesignmanagementrepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodedesignmanagementrepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodedesignmanagementrepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.groupWikiRepositoryRegistries`
@@ -25432,6 +25437,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodegroupwikirepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodegroupwikirepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodegroupwikirepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodegroupwikirepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodegroupwikirepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.jobArtifactRegistries`
@@ -25451,6 +25457,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodejobartifactregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodejobartifactregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodejobartifactregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodejobartifactregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodejobartifactregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.lfsObjectRegistries`
@@ -25470,6 +25477,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodelfsobjectregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodelfsobjectregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodelfsobjectregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodelfsobjectregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodelfsobjectregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.mergeRequestDiffRegistries`
@@ -25489,6 +25497,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodemergerequestdiffregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodemergerequestdiffregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodemergerequestdiffregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodemergerequestdiffregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodemergerequestdiffregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.packageFileRegistries`
@@ -25508,6 +25517,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodepackagefileregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodepackagefileregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodepackagefileregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodepackagefileregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodepackagefileregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.pagesDeploymentRegistries`
@@ -25527,6 +25537,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodepagesdeploymentregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodepagesdeploymentregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodepagesdeploymentregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodepagesdeploymentregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodepagesdeploymentregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.pipelineArtifactRegistries`
@@ -25546,6 +25557,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodepipelineartifactregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodepipelineartifactregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodepipelineartifactregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodepipelineartifactregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodepipelineartifactregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.projectRepositoryRegistries`
@@ -25565,6 +25577,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodeprojectrepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodeprojectrepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodeprojectrepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodeprojectrepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodeprojectrepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.projectWikiRepositoryRegistries`
@@ -25584,6 +25597,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodeprojectwikirepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodeprojectwikirepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodeprojectwikirepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodeprojectwikirepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodeprojectwikirepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.snippetRepositoryRegistries`
@@ -25603,6 +25617,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodesnippetrepositoryregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodesnippetrepositoryregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodesnippetrepositoryregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodesnippetrepositoryregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodesnippetrepositoryregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.terraformStateVersionRegistries`
@@ -25622,6 +25637,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodeterraformstateversionregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodeterraformstateversionregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodeterraformstateversionregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodeterraformstateversionregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodeterraformstateversionregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ##### `GeoNode.uploadRegistries`
@@ -25641,6 +25657,7 @@ four standard [pagination arguments](#pagination-arguments):
 | <a id="geonodeuploadregistriesids"></a>`ids` | [`[ID!]`](#id) | Filters registries by their ID. |
 | <a id="geonodeuploadregistrieskeyword"></a>`keyword` **{warning-solid}** | [`String`](#string) | **Deprecated** in GitLab 17.9. A keyword search feature on Geo registries will not be built in the UI due to poor search UX and performance. |
 | <a id="geonodeuploadregistriesreplicationstate"></a>`replicationState` | [`ReplicationStateEnum`](#replicationstateenum) | Filters registries by their replication state. |
+| <a id="geonodeuploadregistriessort"></a>`sort` | [`GeoRegistrySort`](#georegistrysort) | Sort registries by given criteria. |
 | <a id="geonodeuploadregistriesverificationstate"></a>`verificationState` | [`VerificationStateEnum`](#verificationstateenum) | Filters registries by their verification state. |
 
 ### `GitlabInstanceFeatureFlag`
@@ -41051,6 +41068,19 @@ Geo registry class.
 | <a id="georegistryclassterraform_state_version_registry"></a>`TERRAFORM_STATE_VERSION_REGISTRY` | Geo::TerraformStateVersionRegistry registry class. |
 | <a id="georegistryclassupload_registry"></a>`UPLOAD_REGISTRY` | Geo::UploadRegistry registry class. |
 
+### `GeoRegistrySort`
+
+Values for sorting Geo registries.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="georegistrysortid_asc"></a>`ID_ASC` | ID by ascending order. |
+| <a id="georegistrysortid_desc"></a>`ID_DESC` | ID by descending order. |
+| <a id="georegistrysortlast_synced_at_asc"></a>`LAST_SYNCED_AT_ASC` | Latest sync date by ascending order. |
+| <a id="georegistrysortlast_synced_at_desc"></a>`LAST_SYNCED_AT_DESC` | Latest sync date by descending order. |
+| <a id="georegistrysortverified_at_asc"></a>`VERIFIED_AT_ASC` | Latest verification date by ascending order. |
+| <a id="georegistrysortverified_at_desc"></a>`VERIFIED_AT_DESC` | Latest verification date by descending order. |
+
 ### `GitlabSubscriptionsAddOnType`
 
 Types of add-ons.
diff --git a/ee/app/finders/geo/framework_registry_finder.rb b/ee/app/finders/geo/framework_registry_finder.rb
index 0b41ed716ab4c2137242301ac59c99ddf87814c1..d79425cd86dbf0df43dc734900ee711cdff5b16b 100644
--- a/ee/app/finders/geo/framework_registry_finder.rb
+++ b/ee/app/finders/geo/framework_registry_finder.rb
@@ -24,7 +24,7 @@ def execute
         registry_entries = by_replication_state(registry_entries)
         registry_entries = by_verification_state(registry_entries)
         registry_entries = by_keyword(registry_entries)
-        registry_entries.ordered_by_id
+        ordered(registry_entries)
       end
 
       private
@@ -76,6 +76,15 @@ def by_keyword(registry_entries)
 
         registry_entries.with_search(params[:keyword])
       end
+
+      def ordered(registry_entries)
+        if params[:sort].to_s.include?('verified_at') && verification_disabled?
+          raise ArgumentError, "Sorting by verified_at is not supported " \
+            "because verification is not enabled for #{replicator_class.model}"
+        end
+
+        registry_entries.ordered_by(params[:sort])
+      end
     end
   end
 end
diff --git a/ee/app/graphql/resolvers/geo/registries_resolver.rb b/ee/app/graphql/resolvers/geo/registries_resolver.rb
index 58d644c5ef8015cfbd7df9fe146e5eeaadd17727..5a2d6ccd88a3776d3ad134f6263df350ff8e0795 100644
--- a/ee/app/graphql/resolvers/geo/registries_resolver.rb
+++ b/ee/app/graphql/resolvers/geo/registries_resolver.rb
@@ -36,6 +36,10 @@ def self.replicator_class
             milestone: '17.9'
           }
 
+        argument :sort, ::Types::Geo::RegistrySortEnum,
+          required: false,
+          description: 'Sort registries by given criteria.'
+
         def resolve(**args)
           return registry_class.none unless geo_node_is_current?
 
@@ -52,7 +56,8 @@ def registry_finder_params(args)
             ids: registry_ids(args[:ids]),
             replication_state: args[:replication_state],
             verification_state: args[:verification_state],
-            keyword: args[:keyword]
+            keyword: args[:keyword],
+            sort: args[:sort]
           }.compact
         end
 
diff --git a/ee/app/graphql/types/geo/registry_sort_enum.rb b/ee/app/graphql/types/geo/registry_sort_enum.rb
new file mode 100644
index 0000000000000000000000000000000000000000..69ec403b669861c2bbfe638edc20a6a6a9eddff9
--- /dev/null
+++ b/ee/app/graphql/types/geo/registry_sort_enum.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Types
+  module Geo
+    class RegistrySortEnum < BaseEnum
+      graphql_name 'GeoRegistrySort'
+      description 'Values for sorting Geo registries'
+
+      value 'ID_ASC', description: 'ID by ascending order.', value: :id_asc
+      value 'ID_DESC', description: 'ID by descending order.', value: :id_desc
+      value 'VERIFIED_AT_ASC', description: 'Latest verification date by ascending order.', value: :verified_at_asc
+      value 'VERIFIED_AT_DESC', description: 'Latest verification date by descending order.', value: :verified_at_desc
+      value 'LAST_SYNCED_AT_ASC', description: 'Latest sync date by ascending order.', value: :last_synced_at_asc
+      value 'LAST_SYNCED_AT_DESC', description: 'Latest sync date by descending order.', value: :last_synced_at_desc
+    end
+  end
+end
diff --git a/ee/app/models/geo/base_registry.rb b/ee/app/models/geo/base_registry.rb
index 263a06ede4484ba263be81ac4f32ec287c13212f..daa463ea1c0c29c2632639f2a9078524c75eef54 100644
--- a/ee/app/models/geo/base_registry.rb
+++ b/ee/app/models/geo/base_registry.rb
@@ -28,6 +28,23 @@ def self.ordered_by_id
     order(:id)
   end
 
+  def self.ordered_by(method)
+    case method.to_s
+    when 'id_desc'
+      order(id: :desc)
+    when 'verified_at_asc'
+      order(verified_at: :asc)
+    when 'verified_at_desc'
+      order(verified_at: :desc)
+    when 'last_synced_at_asc'
+      order(last_synced_at: :asc)
+    when 'last_synced_at_desc'
+      order(last_synced_at: :desc)
+    else
+      ordered_by_id
+    end
+  end
+
   def self.after_bulk_mark_update_cursor(bulk_mark_update_cursor)
     where("id > ?", bulk_mark_update_cursor)
   end
diff --git a/ee/spec/graphql/types/geo/registry_sort_enum_spec.rb b/ee/spec/graphql/types/geo/registry_sort_enum_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7dfb23c0043fa632fd8215ac133f94e2abf8273e
--- /dev/null
+++ b/ee/spec/graphql/types/geo/registry_sort_enum_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['GeoRegistrySort'], feature_category: :geo_replication do
+  it { expect(described_class.graphql_name).to eq('GeoRegistrySort') }
+
+  it 'exposes the correct registry sort parameters' do
+    parameters = %w[ID_ASC ID_DESC VERIFIED_AT_ASC VERIFIED_AT_DESC LAST_SYNCED_AT_ASC LAST_SYNCED_AT_DESC]
+    expect(described_class.values.keys).to include(*parameters)
+  end
+end
diff --git a/ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb b/ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb
index 413624110ee7d4e6f7df045c5df3ebb30c423d23..8490a6b368a9104e752976befaf5f336b4458e0a 100644
--- a/ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb
+++ b/ee/spec/support/shared_examples/finders/geo/framework_registry_finder_shared_examples.rb
@@ -5,20 +5,29 @@
 
   let(:replicator_class) { Gitlab::Geo::Replicator.for_class_name(described_class.name) }
   let(:model_class) { replicator_class.model }
-  let(:factory_traits) { replicator_class.verification_enabled? ? [:synced, :verification_succeeded] : [:synced] }
-
-  # rubocop:disable Rails/SaveBang
-  let!(:registry1) { create(registry_factory, :synced) }
-  let!(:registry2) { create(registry_factory, *factory_traits) }
-  let!(:registry3) { create(registry_factory) }
-  let!(:registry4) { create(registry_factory, *factory_traits) }
-  # rubocop:enable Rails/SaveBang
 
   let(:params) { {} }
 
-  subject(:registries) { described_class.new(user, params).execute }
+  before do
+    # Make sure a Geo node is stubbed to ensure .verification_enabled? doesn't return false
+    stub_current_geo_node(create(:geo_node))
+  end
 
   describe '#execute' do
+    let(:factory_traits) do
+      replicator_class.verification_enabled? ? [:synced, :verification_succeeded] : [:synced]
+    end
+
+    # rubocop:disable Rails/SaveBang  -- This is not creating a record but a factory.
+    # See Rubocop issue: https://github.com/thoughtbot/factory_bot/issues/1620
+    let!(:registry1) { create(registry_factory, :synced) }
+    let!(:registry2) { create(registry_factory, *factory_traits) }
+    let!(:registry3) { create(registry_factory) }
+    let!(:registry4) { create(registry_factory, *factory_traits) }
+    # rubocop:enable Rails/SaveBang
+
+    subject(:registries) { described_class.new(user, params).execute }
+
     context 'when user cannot read all Geo' do
       let_it_be(:user) { create(:user) }
 
@@ -155,6 +164,67 @@ def searchable_attributes
           end
         end
 
+        context 'with a sort param' do
+          context 'when sorting by id descending' do
+            let(:params) { { sort: 'id_desc' } }
+
+            it 'returns all registries sorted by id desc' do
+              expected_result = [registry4, registry3, registry2, registry1]
+
+              expect(registries.to_a).to eq(expected_result)
+            end
+          end
+
+          context 'when sorting by last_synced_at ascending' do
+            let(:params) { { sort: 'last_synced_at_asc' } }
+
+            it 'returns all registries sorted by last_synced_at asc' do
+              expected_result = [registry1, registry2, registry4, registry3]
+
+              expect(registries.to_a).to eq(expected_result)
+            end
+          end
+
+          context 'when sorting by verified_at' do
+            let(:params) { { sort: 'verified_at_desc' } }
+
+            context 'with verification enabled' do
+              before do
+                skip_if_verification_is_not_enabled
+              end
+
+              it 'returns all registries sorted by verified_at desc' do
+                expected_result = [registry1, registry3, registry4, registry2]
+
+                expect(registries.to_a).to eq(expected_result)
+              end
+            end
+
+            context 'with verification disabled' do
+              before do
+                skip_if_verification_is_enabled
+              end
+
+              it 'raises ArgumentError' do
+                message = "Sorting by verified_at is not supported " \
+                  "because verification is not enabled for #{replicator_class.model}"
+
+                expect { registries }.to raise_error(ArgumentError, message)
+              end
+            end
+          end
+        end
+
+        context 'with a nil sort param' do
+          let(:params) { { sort: nil } }
+
+          it 'returns all registries sorted by id ascending' do
+            expected_result = [registry1, registry2, registry3, registry4]
+
+            expect(registries.to_a).to eq(expected_result)
+          end
+        end
+
         context 'with no params' do
           it 'returns all registries' do
             expect(registries.to_a).to contain_exactly(registry1, registry2, registry3, registry4)
diff --git a/ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb b/ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb
index 88726d80fc94eca8eef9c6c9addfc0fb712f3da7..70b17d1daf533e68ab89a9f97e5d80f225b829e7 100644
--- a/ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb
+++ b/ee/spec/support/shared_examples/graphql/geo/geo_registries_resolver_shared_examples.rb
@@ -53,6 +53,15 @@
             end
           end
 
+          context 'when the sort argument is present' do
+            it 'returns all registries in sort order' do
+              args = { sort: 'id_desc'.upcase }
+              expected = [registry4, registry3, registry2, registry1]
+
+              expect(resolve_registries(args).to_a).to eq(expected)
+            end
+          end
+
           context 'with verification enabled' do
             before do
               skip_if_verification_is_not_enabled
@@ -66,6 +75,15 @@
                 expect(resolve_registries(args).to_a).to eq(expected)
               end
             end
+
+            context 'when the verified_at sort argument is present' do
+              it 'returns registries with requested verified_at, in order' do
+                args = { sort: 'verified_at_asc'.upcase }
+                expected = [registry2, registry4, registry1, registry3]
+
+                expect(resolve_registries(args).to_a).to eq(expected)
+              end
+            end
           end
 
           context 'with verification disabled' do
@@ -82,6 +100,16 @@
                 expect { resolve_registries(args) }.to raise_error(ArgumentError, message)
               end
             end
+
+            context 'when the verified_at sort argument is present' do
+              it 'raises ArgumentError' do
+                args = { sort: 'verified_at_asc'.upcase }
+                message = "Sorting by verified_at is not supported " \
+                  "because verification is not enabled for #{replicator_class.model}"
+
+                expect { resolve_registries(args) }.to raise_error(ArgumentError, message)
+              end
+            end
           end
         end
 
diff --git a/ee/spec/support/shared_examples/models/geo_framework_registry_shared_examples.rb b/ee/spec/support/shared_examples/models/geo_framework_registry_shared_examples.rb
index ff911159281e8b3cdeb5c99d587614844bdc2b7d..e4d8254fcc5f9e30709c3b54fa634014de12b9fe 100644
--- a/ee/spec/support/shared_examples/models/geo_framework_registry_shared_examples.rb
+++ b/ee/spec/support/shared_examples/models/geo_framework_registry_shared_examples.rb
@@ -100,6 +100,38 @@
     end
   end
 
+  describe '.ordered_by' do
+    let!(:registry1) { create(registry_class_factory, last_synced_at: 3.hours.ago, verified_at: 6.hours.ago) }
+    let!(:registry2) { create(registry_class_factory, last_synced_at: 6.hours.ago, verified_at: 3.hours.ago) }
+    # rubocop:disable Rails/SaveBang -- Rubocop believes this is a record creation, not factory :(
+    let!(:registry3) { create(registry_class_factory) }
+    # rubocop:enable Rails/SaveBang
+
+    it 'orders records by id ASC by default' do
+      expect(described_class.ordered_by('').to_a).to eq([registry1, registry2, registry3])
+    end
+
+    it 'orders records by id DESC' do
+      expect(described_class.ordered_by('id_desc').to_a).to eq([registry3, registry2, registry1])
+    end
+
+    it 'orders records by last_synced_at DESC' do
+      expect(described_class.ordered_by('last_synced_at_desc').to_a).to eq([registry3, registry1, registry2])
+    end
+
+    it 'orders records by last_synced_at ASC' do
+      expect(described_class.ordered_by('last_synced_at_asc').to_a).to eq([registry2, registry1, registry3])
+    end
+
+    it 'orders records by verified_at DESC' do
+      expect(described_class.ordered_by('verified_at_desc').to_a).to eq([registry3, registry2, registry1])
+    end
+
+    it 'orders records by verified_at ASC' do
+      expect(described_class.ordered_by('verified_at_asc').to_a).to eq([registry1, registry2, registry3])
+    end
+  end
+
   describe '.fail_sync_timeouts' do
     it 'marks started records as failed if they are expired' do
       record1 = create(registry_class_factory, :started, last_synced_at: 9.hours.ago)