diff --git a/app/models/project.rb b/app/models/project.rb
index 45d334bd09a0e464c477353b3560422d7fb5bf40..499e5d0fd90ad7a654e367d5a784b6f86be1baf7 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -2318,7 +2318,13 @@ def pipeline_status
   def add_export_job(current_user:, after_export_strategy: nil, params: {})
     check_project_export_limit!
 
-    job_id = ProjectExportWorker.perform_async(current_user.id, self.id, after_export_strategy, params)
+    job_id = if Feature.enabled?(:parallel_project_export, current_user)
+               Projects::ImportExport::CreateRelationExportsWorker
+                 .perform_async(current_user.id, self.id, after_export_strategy, params)
+             else
+               ProjectExportWorker
+                 .perform_async(current_user.id, self.id, after_export_strategy, params)
+             end
 
     if job_id
       Gitlab::AppLogger.info "Export job started for project ID #{self.id} with job ID #{job_id}"
diff --git a/app/workers/projects/import_export/create_relation_exports_worker.rb b/app/workers/projects/import_export/create_relation_exports_worker.rb
index e115c8917b183544e61ab1a375500876f2204baa..ac5fd343a6ce9d07269bc35d74ae6605a70fe015 100644
--- a/app/workers/projects/import_export/create_relation_exports_worker.rb
+++ b/app/workers/projects/import_export/create_relation_exports_worker.rb
@@ -33,14 +33,14 @@ def perform(user_id, project_id, after_export_strategy = {}, params = {})
           RelationExportWorker.with_status.perform_async(relation_export.id, user_id, params)
         end
 
+        project_export_job.start!
+
         WaitRelationExportsWorker.perform_in(
           INITIAL_DELAY,
           project_export_job.id,
           user_id,
           after_export_strategy
         )
-
-        project_export_job.start!
       end
       # rubocop: enable CodeReuse/ActiveRecord
     end
diff --git a/config/feature_flags/development/parallel_project_export.yml b/config/feature_flags/development/parallel_project_export.yml
new file mode 100644
index 0000000000000000000000000000000000000000..da4e9a0417e484cf0f8e120e2c27e9cccc728bc5
--- /dev/null
+++ b/config/feature_flags/development/parallel_project_export.yml
@@ -0,0 +1,8 @@
+---
+name: parallel_project_export
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145165
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/442337
+milestone: '16.10'
+type: development
+group: group::import and integrate
+default_enabled: false
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index bc3a11934b5a075ed5ae433a8fd2cca1fdaba41e..438cf3dd410f3947f08f970e04bc4a051a38a8c4 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -7593,34 +7593,56 @@ def has_external_wiki
     let_it_be(:user) { create(:user) }
     let_it_be(:project) { create(:project) }
 
-    context 'when project storage_size does not exceed the application setting max_export_size' do
-      it 'starts project export worker' do
-        stub_application_setting(max_export_size: 1)
-        allow(project.statistics).to receive(:storage_size).and_return(0.megabytes)
-
-        expect(ProjectExportWorker).to receive(:perform_async).with(user.id, project.id, nil, {})
+    context 'when parallel_project_export feature flag is enabled' do
+      it 'enqueues CreateionProjectExportWorker' do
+        expect(Projects::ImportExport::CreateRelationExportsWorker)
+          .to receive(:perform_async)
+          .with(user.id, project.id, nil, {})
 
         project.add_export_job(current_user: user)
       end
     end
 
-    context 'when project storage_size exceeds the application setting max_export_size' do
-      it 'raises Project::ExportLimitExceeded' do
-        stub_application_setting(max_export_size: 1)
-        allow(project.statistics).to receive(:storage_size).and_return(2.megabytes)
-
-        expect(ProjectExportWorker).not_to receive(:perform_async).with(user.id, project.id, nil, {})
-        expect { project.add_export_job(current_user: user) }.to raise_error(Project::ExportLimitExceeded)
+    context 'when parallel_project_export feature flag is disabled' do
+      before do
+        stub_feature_flags(parallel_project_export: false)
       end
-    end
 
-    context 'when application setting max_export_size is not set' do
-      it 'starts project export worker' do
-        allow(project.statistics).to receive(:storage_size).and_return(2.megabytes)
+      it 'enquques ProjectExportWorker' do
         expect(ProjectExportWorker).to receive(:perform_async).with(user.id, project.id, nil, {})
 
         project.add_export_job(current_user: user)
       end
+
+      context 'when project storage_size does not exceed the application setting max_export_size' do
+        it 'starts project export worker' do
+          stub_application_setting(max_export_size: 1)
+          allow(project.statistics).to receive(:storage_size).and_return(0.megabytes)
+
+          expect(ProjectExportWorker).to receive(:perform_async).with(user.id, project.id, nil, {})
+
+          project.add_export_job(current_user: user)
+        end
+      end
+
+      context 'when project storage_size exceeds the application setting max_export_size' do
+        it 'raises Project::ExportLimitExceeded' do
+          stub_application_setting(max_export_size: 1)
+          allow(project.statistics).to receive(:storage_size).and_return(2.megabytes)
+
+          expect(ProjectExportWorker).not_to receive(:perform_async).with(user.id, project.id, nil, {})
+          expect { project.add_export_job(current_user: user) }.to raise_error(Project::ExportLimitExceeded)
+        end
+      end
+
+      context 'when application setting max_export_size is not set' do
+        it 'starts project export worker' do
+          allow(project.statistics).to receive(:storage_size).and_return(2.megabytes)
+          expect(ProjectExportWorker).to receive(:perform_async).with(user.id, project.id, nil, {})
+
+          project.add_export_job(current_user: user)
+        end
+      end
     end
   end
 
diff --git a/spec/requests/api/project_export_spec.rb b/spec/requests/api/project_export_spec.rb
index 6d5591d75002f30ed4cda78d69c47a6f69c1ccc5..02c2b9bceb211d55d0e37b9c04be725239e4eb5e 100644
--- a/spec/requests/api/project_export_spec.rb
+++ b/spec/requests/api/project_export_spec.rb
@@ -519,15 +519,27 @@
       end
 
       context 'when overriding description' do
-        it 'starts', :sidekiq_might_not_need_inline do
-          params = { description: "Foo" }
+        context 'when parallel_project_export feature flag is disabled' do
+          it 'starts export service', :sidekiq_might_not_need_inline do
+            stub_feature_flags(parallel_project_export: false)
 
-          expect_next_instance_of(Projects::ImportExport::ExportService) do |service|
-            expect(service).to receive(:execute)
+            params = { description: "Foo" }
+
+            expect_next_instance_of(Projects::ImportExport::ExportService) do |service|
+              expect(service).to receive(:execute)
+            end
+            post api(path, project.first_owner), params: params
+
+            expect(response).to have_gitlab_http_status(:accepted)
           end
-          post api(path, project.first_owner), params: params
+        end
 
-          expect(response).to have_gitlab_http_status(:accepted)
+        context 'when parallel_project_export feature flag is enabled' do
+          it 'enqueues CreateRelationExportsWorker' do
+            expect(Projects::ImportExport::CreateRelationExportsWorker).to receive(:perform_async)
+
+            post api(path, project.first_owner), params: params
+          end
         end
       end
     end