diff --git a/app/graphql/resolvers/organizations/projects_resolver.rb b/app/graphql/resolvers/organizations/projects_resolver.rb
index 836fe0ae0597316c9317f3851b634e03f2fb6f74..310e2d8454073e8154abbed351e4dbca85f77df4 100644
--- a/app/graphql/resolvers/organizations/projects_resolver.rb
+++ b/app/graphql/resolvers/organizations/projects_resolver.rb
@@ -11,8 +11,21 @@ class ProjectsResolver < BaseResolver
 
       alias_method :organization, :object
 
-      def resolve
-        ::ProjectsFinder.new(current_user: current_user, params: { organization: organization }).execute
+      argument :sort, GraphQL::Types::String,
+        required: false,
+        description: "Sort order of results. Format: `<field_name>_<sort_direction>`, " \
+                     "for example: `id_desc` or `name_asc`",
+        alpha: { milestone: '16.9' }
+
+      def resolve(**args)
+        project_finder_params = args.merge(organization: organization)
+
+        if %w[path_asc path_desc].include?(project_finder_params[:sort]) &&
+            Feature.disabled?(:project_path_sort, current_user, type: :gitlab_com_derisk)
+          project_finder_params.delete(:sort)
+        end
+
+        ::ProjectsFinder.new(current_user: current_user, params: project_finder_params).execute
       end
     end
   end
diff --git a/app/models/project.rb b/app/models/project.rb
index 19847978acbdd7c9a576ce6cb16103996cb31d47..7012cb7b25bcc84be66ce3ee9e7e2ba4631b4bf7 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -634,6 +634,8 @@ def self.integration_association_name(name)
   scope :sorted_by_updated_desc, -> { reorder(self.arel_table['updated_at'].desc) }
   scope :sorted_by_stars_desc, -> { reorder(self.arel_table['star_count'].desc) }
   scope :sorted_by_stars_asc, -> { reorder(self.arel_table['star_count'].asc) }
+  scope :sorted_by_path_asc, -> { reorder(self.arel_table['path'].asc) }
+  scope :sorted_by_path_desc, -> { reorder(self.arel_table['path'].desc) }
   # Sometimes queries (e.g. using CTEs) require explicit disambiguation with table name
   scope :projects_order_id_asc, -> { reorder(self.arel_table['id'].asc) }
   scope :projects_order_id_desc, -> { reorder(self.arel_table['id'].desc) }
@@ -956,6 +958,10 @@ def sort_by_attribute(method)
         sorted_by_updated_desc
       when 'latest_activity_asc'
         sorted_by_updated_asc
+      when 'path_asc'
+        sorted_by_path_asc
+      when 'path_desc'
+        sorted_by_path_desc
       when 'stars_desc'
         sorted_by_stars_desc
       when 'stars_asc'
diff --git a/config/feature_flags/gitlab_com_derisk/project_path_sort.yml b/config/feature_flags/gitlab_com_derisk/project_path_sort.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a550bbea54dba06d6bd6f9852f74e57ae7760d0d
--- /dev/null
+++ b/config/feature_flags/gitlab_com_derisk/project_path_sort.yml
@@ -0,0 +1,9 @@
+---
+name: project_path_sort
+feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/409312
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/142390
+rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/production/-/issues/17492
+milestone: '16.9'
+group: group::tenant scale
+type: gitlab_com_derisk
+default_enabled: false
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 27cbeeb3d9cfa985e861476b90862f59e870b4c4..1d2b8b0143e25c4211d26e8ba6e87ea4e9022da5 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -23550,7 +23550,6 @@ Active period time range for on-call rotation.
 | <a id="organizationname"></a>`name` **{warning-solid}** | [`String!`](#string) | **Introduced** in 16.4. **Status**: Experiment. Name of the organization. |
 | <a id="organizationorganizationusers"></a>`organizationUsers` **{warning-solid}** | [`OrganizationUserConnection!`](#organizationuserconnection) | **Introduced** in 16.4. **Status**: Experiment. Users with access to the organization. |
 | <a id="organizationpath"></a>`path` **{warning-solid}** | [`String!`](#string) | **Introduced** in 16.4. **Status**: Experiment. Path of the organization. |
-| <a id="organizationprojects"></a>`projects` **{warning-solid}** | [`ProjectConnection!`](#projectconnection) | **Introduced** in 16.8. **Status**: Experiment. Projects within this organization that the user has access to. |
 | <a id="organizationweburl"></a>`webUrl` **{warning-solid}** | [`String!`](#string) | **Introduced** in 16.6. **Status**: Experiment. Web URL of the organization. |
 
 #### Fields with arguments
@@ -23576,6 +23575,26 @@ four standard [pagination arguments](#connection-pagination-arguments):
 | <a id="organizationgroupssearch"></a>`search` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.4. **Status**: Experiment. Search query for group name or full path. |
 | <a id="organizationgroupssort"></a>`sort` **{warning-solid}** | [`OrganizationGroupSort`](#organizationgroupsort) | **Introduced** in 16.4. **Status**: Experiment. Criteria to sort organization groups by. |
 
+##### `Organization.projects`
+
+Projects within this organization that the user has access to.
+
+NOTE:
+**Introduced** in 16.8.
+**Status**: Experiment.
+
+Returns [`ProjectConnection!`](#projectconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, and `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="organizationprojectssort"></a>`sort` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.9. **Status**: Experiment. Sort order of results. Format: `<field_name>_<sort_direction>`, for example: `id_desc` or `name_asc`. |
+
 ### `OrganizationStateCounts`
 
 Represents the total number of organizations for the represented states.
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 03e7b69181fa5758a4d55343c35e7957e9bcdd16..d7037df66782be8ba8fd23d6f2ec27042e629436 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -2112,6 +2112,18 @@ def has_external_wiki
 
       expect(projects).to eq([project3, project1, project2])
     end
+
+    it 'reorders the input relation by path asc' do
+      projects = described_class.sort_by_attribute(:path_asc)
+
+      expect(projects).to eq([project1, project2, project3].sort_by(&:path))
+    end
+
+    it 'reorders the input relation by path desc' do
+      projects = described_class.sort_by_attribute(:path_desc)
+
+      expect(projects).to eq([project1, project2, project3].sort_by(&:path).reverse)
+    end
   end
 
   describe '.with_shared_runners_enabled' do
diff --git a/spec/requests/api/graphql/organizations/organization_query_spec.rb b/spec/requests/api/graphql/organizations/organization_query_spec.rb
index 14becd52e93fbb384e6dddcee08028931dca4ec0..37256c22c231595d72819b792170dac87ad15bcb 100644
--- a/spec/requests/api/graphql/organizations/organization_query_spec.rb
+++ b/spec/requests/api/graphql/organizations/organization_query_spec.rb
@@ -4,6 +4,7 @@
 
 RSpec.describe 'getting organization information', feature_category: :cell do
   include GraphqlHelpers
+  using RSpec::Parameterized::TableSyntax
 
   let(:query) { graphql_query_for(:organization, { id: organization.to_global_id }, organization_fields) }
   let(:current_user) { user }
@@ -154,8 +155,6 @@ def run_query
       end
 
       context 'with `sort` argument' do
-        using RSpec::Parameterized::TableSyntax
-
         let(:authorized_groups) { [public_group, private_group, other_group] }
 
         where(:field, :direction, :sorted_groups) do
@@ -216,14 +215,46 @@ def run_query
         expect(projects).to contain_exactly(a_graphql_entity_for(project))
       end
 
-      it_behaves_like 'sorted paginated query' do
-        include_context 'no sort argument'
-
+      describe 'project sorting' do
         let_it_be(:another_project) { create(:project, organization: organization) { |p| p.add_developer(user) } }
         let_it_be(:another_project2) { create(:project, organization: organization) { |p| p.add_developer(user) } }
-        let(:first_param) { 2 }
-        let(:data_path) { [:organization, :projects] }
-        let(:all_records) { [another_project2, another_project, project].map { |p| global_id_of(p).to_s } }
+        let_it_be(:all_projects) { [another_project2, another_project, project] }
+        let_it_be(:first_param) { 2 }
+        let_it_be(:data_path) { [:organization, :projects] }
+
+        where(:field, :direction, :sorted_projects) do
+          'id'   | 'asc'  | lazy { all_projects.sort_by(&:id) }
+          'id'   | 'desc' | lazy { all_projects.sort_by(&:id).reverse }
+          'name' | 'asc'  | lazy { all_projects.sort_by(&:name) }
+          'name' | 'desc' | lazy { all_projects.sort_by(&:name).reverse }
+          'path' | 'asc'  | lazy { all_projects.sort_by(&:path) }
+          'path' | 'desc' | lazy { all_projects.sort_by(&:path).reverse }
+        end
+
+        with_them do
+          it_behaves_like 'sorted paginated query' do
+            let(:sort_param) { "#{field}_#{direction}" }
+            let(:all_records) { sorted_projects.map { |p| global_id_of(p).to_s } }
+          end
+        end
+
+        context 'with project_path_sort disabled sorts the projects by id_desc' do
+          before do
+            stub_feature_flags(project_path_sort: false)
+          end
+
+          where(:field, :direction) do
+            'path' | 'asc'
+            'path' | 'desc'
+          end
+
+          with_them do
+            it_behaves_like 'sorted paginated query' do
+              let(:sort_param) { "#{field}_#{direction}" }
+              let(:all_records) { all_projects.sort_by(&:id).reverse.map { |p| global_id_of(p).to_s } }
+            end
+          end
+        end
       end
 
       def pagination_query(params)