diff --git a/app/graphql/resolvers/members_resolver.rb b/app/graphql/resolvers/members_resolver.rb
index 827db54134a1d4c1d6d02de654733a863e0634c5..3d7894fdd6a055b03d498ab0a9434e6310e5e01e 100644
--- a/app/graphql/resolvers/members_resolver.rb
+++ b/app/graphql/resolvers/members_resolver.rb
@@ -11,6 +11,10 @@ class MembersResolver < BaseResolver
               required: false,
               description: 'Search query.'
 
+    argument :sort, ::Types::MemberSortEnum,
+              required: false,
+              description: 'sort query.'
+
     def resolve_with_lookahead(**args)
       authorize!(object)
 
diff --git a/app/graphql/types/member_sort_enum.rb b/app/graphql/types/member_sort_enum.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f3291dda13b64a9b0f295c02a46a6c91572989e1
--- /dev/null
+++ b/app/graphql/types/member_sort_enum.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Types
+  class MemberSortEnum < SortEnum
+    graphql_name 'MemberSort'
+    description 'Values for sorting members'
+
+    value 'ACCESS_LEVEL_ASC', 'Access level ascending order.', value: :access_level_asc
+    value 'ACCESS_LEVEL_DESC', 'Access level descending order.', value: :access_level_desc
+    value 'USER_FULL_NAME_ASC', "User's full name ascending order.", value: :name_asc
+    value 'USER_FULL_NAME_DESC', "User's full name descending order.", value: :name_desc
+  end
+end
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index 65fb62a814f815a01a42f66b9ad786ef0839aa53..eccb004b503ed723fcad7264b06691ac6ac5877c 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -43,6 +43,33 @@ def simple_sorts
       }
     end
 
+    def build_keyset_order_on_joined_column(scope:, attribute_name:, column:, direction:, nullable:)
+      reversed_direction = direction == :asc ? :desc : :asc
+
+      # rubocop: disable GitlabSecurity/PublicSend
+      order = ::Gitlab::Pagination::Keyset::Order.build(
+        [
+          ::Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+            attribute_name: attribute_name,
+            column_expression: column,
+            order_expression: column.send(direction).send(nullable),
+            reversed_order_expression: column.send(reversed_direction).send(nullable),
+            order_direction: direction,
+            distinct: false,
+            add_to_projections: true,
+            nullable: nullable
+          ),
+          ::Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+            attribute_name: 'id',
+            order_expression: arel_table['id'].desc
+          )
+        ]
+      )
+      # rubocop: enable GitlabSecurity/PublicSend
+
+      order.apply_cursor_conditions(scope).reorder(order)
+    end
+
     private
 
     def highest_label_priority(target_type_column: nil, target_type: nil, target_column:, project_column:, excluded_labels: [])
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 1de2075b456fd4c1f7038fe534793b1e651379a9..153747c75df915f6c8a4e9ef4b19a137424bf11f 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -254,32 +254,6 @@ class << self
     alias_method :with_state, :with_state_id
     alias_method :with_states, :with_state_ids
 
-    def build_keyset_order_on_joined_column(scope:, attribute_name:, column:, direction:, nullable:)
-      reversed_direction = direction == :asc ? :desc : :asc
-
-      # rubocop: disable GitlabSecurity/PublicSend
-      order = ::Gitlab::Pagination::Keyset::Order.build(
-        [
-          ::Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
-            attribute_name: attribute_name,
-            column_expression: column,
-            order_expression: column.send(direction).send(nullable),
-            reversed_order_expression: column.send(reversed_direction).send(nullable),
-            order_direction: direction,
-            distinct: false,
-            add_to_projections: true,
-            nullable: nullable
-          ),
-          ::Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
-            attribute_name: 'id',
-            order_expression: arel_table['id'].desc
-          )
-        ])
-      # rubocop: enable GitlabSecurity/PublicSend
-
-      order.apply_cursor_conditions(scope).order(order)
-    end
-
     override :order_upvotes_desc
     def order_upvotes_desc
       reorder(upvotes_count: :desc)
diff --git a/app/models/member.rb b/app/models/member.rb
index 186fcd8759f252342a62e40129046901533b8410..c5351d5447bee894588529dacaf16662fbcee2d7 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -184,14 +184,85 @@ class Member < ApplicationRecord
     unscoped.from(distinct_members, :members)
   end
 
-  scope :order_name_asc, -> { left_join_users.reorder(User.arel_table[:name].asc.nulls_last) }
-  scope :order_name_desc, -> { left_join_users.reorder(User.arel_table[:name].desc.nulls_last) }
-  scope :order_recent_sign_in, -> { left_join_users.reorder(User.arel_table[:last_sign_in_at].desc.nulls_last) }
-  scope :order_oldest_sign_in, -> { left_join_users.reorder(User.arel_table[:last_sign_in_at].asc.nulls_last) }
-  scope :order_recent_last_activity, -> { left_join_users.reorder(User.arel_table[:last_activity_on].desc.nulls_last) }
-  scope :order_oldest_last_activity, -> { left_join_users.reorder(User.arel_table[:last_activity_on].asc.nulls_first) }
-  scope :order_recent_created_user, -> { left_join_users.reorder(User.arel_table[:created_at].desc.nulls_last) }
-  scope :order_oldest_created_user, -> { left_join_users.reorder(User.arel_table[:created_at].asc.nulls_first) }
+  scope :order_name_asc, -> do
+    build_keyset_order_on_joined_column(
+      scope: left_join_users,
+      attribute_name: 'member_user_full_name',
+      column: User.arel_table[:name],
+      direction: :asc,
+      nullable: :nulls_last
+    )
+  end
+
+  scope :order_name_desc, -> do
+    build_keyset_order_on_joined_column(
+      scope: left_join_users,
+      attribute_name: 'member_user_full_name',
+      column: User.arel_table[:name],
+      direction: :desc,
+      nullable: :nulls_last
+    )
+  end
+
+  scope :order_oldest_sign_in, -> do
+    build_keyset_order_on_joined_column(
+      scope: left_join_users,
+      attribute_name: 'member_user_last_sign_in_at',
+      column: User.arel_table[:last_sign_in_at],
+      direction: :asc,
+      nullable: :nulls_last
+    )
+  end
+
+  scope :order_recent_sign_in, -> do
+    build_keyset_order_on_joined_column(
+      scope: left_join_users,
+      attribute_name: 'member_user_last_sign_in_at',
+      column: User.arel_table[:last_sign_in_at],
+      direction: :desc,
+      nullable: :nulls_last
+    )
+  end
+
+  scope :order_oldest_last_activity, -> do
+    build_keyset_order_on_joined_column(
+      scope: left_join_users,
+      attribute_name: 'member_user_last_activity_on',
+      column: User.arel_table[:last_activity_on],
+      direction: :asc,
+      nullable: :nulls_first
+    )
+  end
+
+  scope :order_recent_last_activity, -> do
+    build_keyset_order_on_joined_column(
+      scope: left_join_users,
+      attribute_name: 'member_user_last_activity_on',
+      column: User.arel_table[:last_activity_on],
+      direction: :desc,
+      nullable: :nulls_last
+    )
+  end
+
+  scope :order_oldest_created_user, -> do
+    build_keyset_order_on_joined_column(
+      scope: left_join_users,
+      attribute_name: 'member_user_created_at',
+      column: User.arel_table[:created_at],
+      direction: :asc,
+      nullable: :nulls_first
+    )
+  end
+
+  scope :order_recent_created_user, -> do
+    build_keyset_order_on_joined_column(
+      scope: left_join_users,
+      attribute_name: 'member_user_created_at',
+      column: User.arel_table[:created_at],
+      direction: :desc,
+      nullable: :nulls_last
+    )
+  end
 
   scope :on_project_and_ancestors, ->(project) { where(source: [project] + project.ancestors) }
 
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index eecdcf8b69ab5153a1e844f495631e003e18126f..7af7272af7a54c8aab79b70729f9421a4b716587 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -12679,6 +12679,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
 | <a id="groupgroupmembersaccesslevels"></a>`accessLevels` | [`[AccessLevelEnum!]`](#accesslevelenum) | Filter members by the given access levels. |
 | <a id="groupgroupmembersrelations"></a>`relations` | [`[GroupMemberRelation!]`](#groupmemberrelation) | Filter members by the given member relations. |
 | <a id="groupgroupmemberssearch"></a>`search` | [`String`](#string) | Search query. |
+| <a id="groupgroupmemberssort"></a>`sort` | [`MemberSort`](#membersort) | sort query. |
 
 ##### `Group.issues`
 
@@ -16594,6 +16595,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
 | ---- | ---- | ----------- |
 | <a id="projectprojectmembersrelations"></a>`relations` | [`[ProjectMemberRelation!]`](#projectmemberrelation) | Filter members by the given member relations. |
 | <a id="projectprojectmemberssearch"></a>`search` | [`String`](#string) | Search query. |
+| <a id="projectprojectmemberssort"></a>`sort` | [`MemberSort`](#membersort) | sort query. |
 
 ##### `Project.release`
 
@@ -20315,6 +20317,25 @@ Possible identifier types for a measurement.
 | <a id="measurementidentifierprojects"></a>`PROJECTS` | Project count. |
 | <a id="measurementidentifierusers"></a>`USERS` | User count. |
 
+### `MemberSort`
+
+Values for sorting members.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="membersortaccess_level_asc"></a>`ACCESS_LEVEL_ASC` | Access level ascending order. |
+| <a id="membersortaccess_level_desc"></a>`ACCESS_LEVEL_DESC` | Access level descending order. |
+| <a id="membersortcreated_asc"></a>`CREATED_ASC` | Created at ascending order. |
+| <a id="membersortcreated_desc"></a>`CREATED_DESC` | Created at descending order. |
+| <a id="membersortupdated_asc"></a>`UPDATED_ASC` | Updated at ascending order. |
+| <a id="membersortupdated_desc"></a>`UPDATED_DESC` | Updated at descending order. |
+| <a id="membersortuser_full_name_asc"></a>`USER_FULL_NAME_ASC` | User's full name ascending order. |
+| <a id="membersortuser_full_name_desc"></a>`USER_FULL_NAME_DESC` | User's full name descending order. |
+| <a id="membersortcreated_asc"></a>`created_asc` **{warning-solid}** | **Deprecated** in 13.5. This was renamed. Use: `CREATED_ASC`. |
+| <a id="membersortcreated_desc"></a>`created_desc` **{warning-solid}** | **Deprecated** in 13.5. This was renamed. Use: `CREATED_DESC`. |
+| <a id="membersortupdated_asc"></a>`updated_asc` **{warning-solid}** | **Deprecated** in 13.5. This was renamed. Use: `UPDATED_ASC`. |
+| <a id="membersortupdated_desc"></a>`updated_desc` **{warning-solid}** | **Deprecated** in 13.5. This was renamed. Use: `UPDATED_DESC`. |
+
 ### `MergeRequestNewState`
 
 New state to apply to a merge request.
diff --git a/spec/graphql/resolvers/group_members_resolver_spec.rb b/spec/graphql/resolvers/group_members_resolver_spec.rb
index bd0b487006210014d33c879b898e075f0ca6d410..d860b87875e0d7ef77a1eb53b599f8cab3e7e45e 100644
--- a/spec/graphql/resolvers/group_members_resolver_spec.rb
+++ b/spec/graphql/resolvers/group_members_resolver_spec.rb
@@ -2,9 +2,11 @@
 
 require 'spec_helper'
 
-RSpec.describe Resolvers::GroupMembersResolver do
+RSpec.describe 'Resolvers::GroupMembersResolver' do
   include GraphqlHelpers
 
+  let(:described_class) { Resolvers::GroupMembersResolver }
+
   specify do
     expect(described_class).to have_nullable_graphql_type(Types::GroupMemberType.connection_type)
   end
diff --git a/spec/graphql/resolvers/project_members_resolver_spec.rb b/spec/graphql/resolvers/project_members_resolver_spec.rb
index 2f4145b321519725909151e473f107b103eb25e4..c38cb3d157bde91d747ad7bdf4fd2ae0c15f0038 100644
--- a/spec/graphql/resolvers/project_members_resolver_spec.rb
+++ b/spec/graphql/resolvers/project_members_resolver_spec.rb
@@ -2,9 +2,11 @@
 
 require 'spec_helper'
 
-RSpec.describe Resolvers::ProjectMembersResolver do
+RSpec.describe 'Resolvers::ProjectMembersResolver' do
   include GraphqlHelpers
 
+  let(:described_class) { Resolvers::ProjectMembersResolver }
+
   it_behaves_like 'querying members with a group' do
     let_it_be(:project) { create(:project, group: group_1) }
     let_it_be(:resource_member) { create(:project_member, user: user_1, project: project) }
diff --git a/spec/support/shared_examples/graphql/members_shared_examples.rb b/spec/support/shared_examples/graphql/members_shared_examples.rb
index f0c50e20a723bccfbd5d297ebc6a92c748253ba0..5cba8baa8298f89122879a2be7bb874280caf0c0 100644
--- a/spec/support/shared_examples/graphql/members_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/members_shared_examples.rb
@@ -52,6 +52,15 @@
       expect(subject).to contain_exactly(resource_member, group_1_member, root_group_member)
     end
 
+    context 'with sort options' do
+      let(:args) { { sort: 'name_asc' } }
+
+      it 'searches users by user name' do
+        # the order is important here
+        expect(subject.items).to eq([root_group_member, resource_member, group_1_member])
+      end
+    end
+
     context 'with search' do
       context 'when the search term matches a user' do
         let(:args) { { search: 'test' } }