diff --git a/db/docs/batched_background_migrations/backfill_bulk_import_export_uploads_group_id.yml b/db/docs/batched_background_migrations/backfill_bulk_import_export_uploads_group_id.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d760e732abc370d464953f8f5ef85f78b6eeaad4
--- /dev/null
+++ b/db/docs/batched_background_migrations/backfill_bulk_import_export_uploads_group_id.yml
@@ -0,0 +1,8 @@
+---
+migration_job_name: BackfillBulkImportExportUploadsGroupId
+description: Backfills sharding key `bulk_import_export_uploads.group_id` from `bulk_import_exports`.
+feature_category: importers
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175723
+milestone: '17.8'
+queued_migration_version: 20241213150054
+finalized_by: # version of the migration that finalized this BBM
diff --git a/db/docs/batched_background_migrations/backfill_bulk_import_export_uploads_project_id.yml b/db/docs/batched_background_migrations/backfill_bulk_import_export_uploads_project_id.yml
new file mode 100644
index 0000000000000000000000000000000000000000..37dd3af6ef1bd0eaa71e4de852c6e92690aa1a0d
--- /dev/null
+++ b/db/docs/batched_background_migrations/backfill_bulk_import_export_uploads_project_id.yml
@@ -0,0 +1,8 @@
+---
+migration_job_name: BackfillBulkImportExportUploadsProjectId
+description: Backfills sharding key `bulk_import_export_uploads.project_id` from `bulk_import_exports`.
+feature_category: importers
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175723
+milestone: '17.8'
+queued_migration_version: 20241213150049
+finalized_by: # version of the migration that finalized this BBM
diff --git a/db/docs/bulk_import_export_uploads.yml b/db/docs/bulk_import_export_uploads.yml
index 8aa85f319c363a035908ce41be7d5f9eb3d9555b..556a24fdc4d04334c6f891248961ec4723001b68 100644
--- a/db/docs/bulk_import_export_uploads.yml
+++ b/db/docs/bulk_import_export_uploads.yml
@@ -27,3 +27,6 @@ desired_sharding_key:
         sharding_key: group_id
         belongs_to: export
 table_size: small
+desired_sharding_key_migration_job_name:
+- BackfillBulkImportExportUploadsProjectId
+- BackfillBulkImportExportUploadsGroupId
diff --git a/db/migrate/20241213150045_add_project_id_to_bulk_import_export_uploads.rb b/db/migrate/20241213150045_add_project_id_to_bulk_import_export_uploads.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0befbf8c9b02bbd4c12b490e98b5148dd355c0db
--- /dev/null
+++ b/db/migrate/20241213150045_add_project_id_to_bulk_import_export_uploads.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddProjectIdToBulkImportExportUploads < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+
+  def change
+    add_column :bulk_import_export_uploads, :project_id, :bigint
+  end
+end
diff --git a/db/migrate/20241213150050_add_group_id_to_bulk_import_export_uploads.rb b/db/migrate/20241213150050_add_group_id_to_bulk_import_export_uploads.rb
new file mode 100644
index 0000000000000000000000000000000000000000..54b8f621446edec752eea757ddc8dadc7a03d22c
--- /dev/null
+++ b/db/migrate/20241213150050_add_group_id_to_bulk_import_export_uploads.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddGroupIdToBulkImportExportUploads < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+
+  def change
+    add_column :bulk_import_export_uploads, :group_id, :bigint
+  end
+end
diff --git a/db/post_migrate/20241213150046_index_bulk_import_export_uploads_on_project_id.rb b/db/post_migrate/20241213150046_index_bulk_import_export_uploads_on_project_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6cb2e4740ef3bd79d701dce4a5f5c82a9b015102
--- /dev/null
+++ b/db/post_migrate/20241213150046_index_bulk_import_export_uploads_on_project_id.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class IndexBulkImportExportUploadsOnProjectId < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_bulk_import_export_uploads_on_project_id'
+
+  def up
+    add_concurrent_index :bulk_import_export_uploads, :project_id, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :bulk_import_export_uploads, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20241213150047_add_bulk_import_export_uploads_project_id_fk.rb b/db/post_migrate/20241213150047_add_bulk_import_export_uploads_project_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5d4d468d359098325880721f2024c7a8cca14672
--- /dev/null
+++ b/db/post_migrate/20241213150047_add_bulk_import_export_uploads_project_id_fk.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddBulkImportExportUploadsProjectIdFk < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_foreign_key :bulk_import_export_uploads, :projects, column: :project_id, on_delete: :cascade
+  end
+
+  def down
+    with_lock_retries do
+      remove_foreign_key :bulk_import_export_uploads, column: :project_id
+    end
+  end
+end
diff --git a/db/post_migrate/20241213150048_add_bulk_import_export_uploads_project_id_trigger.rb b/db/post_migrate/20241213150048_add_bulk_import_export_uploads_project_id_trigger.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8c3f9d1d5f80a05c68582faa814fa6341aa24b8e
--- /dev/null
+++ b/db/post_migrate/20241213150048_add_bulk_import_export_uploads_project_id_trigger.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class AddBulkImportExportUploadsProjectIdTrigger < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+
+  def up
+    install_sharding_key_assignment_trigger(
+      table: :bulk_import_export_uploads,
+      sharding_key: :project_id,
+      parent_table: :bulk_import_exports,
+      parent_sharding_key: :project_id,
+      foreign_key: :export_id
+    )
+  end
+
+  def down
+    remove_sharding_key_assignment_trigger(
+      table: :bulk_import_export_uploads,
+      sharding_key: :project_id,
+      parent_table: :bulk_import_exports,
+      parent_sharding_key: :project_id,
+      foreign_key: :export_id
+    )
+  end
+end
diff --git a/db/post_migrate/20241213150049_queue_backfill_bulk_import_export_uploads_project_id.rb b/db/post_migrate/20241213150049_queue_backfill_bulk_import_export_uploads_project_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8ab88ee5085ad3155a541c6f193a8e5afef7f816
--- /dev/null
+++ b/db/post_migrate/20241213150049_queue_backfill_bulk_import_export_uploads_project_id.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class QueueBackfillBulkImportExportUploadsProjectId < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+  restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
+
+  MIGRATION = "BackfillBulkImportExportUploadsProjectId"
+  DELAY_INTERVAL = 2.minutes
+  BATCH_SIZE = 1000
+  SUB_BATCH_SIZE = 100
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :bulk_import_export_uploads,
+      :id,
+      :project_id,
+      :bulk_import_exports,
+      :project_id,
+      :export_id,
+      job_interval: DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE
+    )
+  end
+
+  def down
+    delete_batched_background_migration(
+      MIGRATION,
+      :bulk_import_export_uploads,
+      :id,
+      [
+        :project_id,
+        :bulk_import_exports,
+        :project_id,
+        :export_id
+      ]
+    )
+  end
+end
diff --git a/db/post_migrate/20241213150051_index_bulk_import_export_uploads_on_group_id.rb b/db/post_migrate/20241213150051_index_bulk_import_export_uploads_on_group_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..77aea3091e01ae17db0a68ecae706f8e4c514044
--- /dev/null
+++ b/db/post_migrate/20241213150051_index_bulk_import_export_uploads_on_group_id.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class IndexBulkImportExportUploadsOnGroupId < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+  disable_ddl_transaction!
+
+  INDEX_NAME = 'index_bulk_import_export_uploads_on_group_id'
+
+  def up
+    add_concurrent_index :bulk_import_export_uploads, :group_id, name: INDEX_NAME
+  end
+
+  def down
+    remove_concurrent_index_by_name :bulk_import_export_uploads, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20241213150052_add_bulk_import_export_uploads_group_id_fk.rb b/db/post_migrate/20241213150052_add_bulk_import_export_uploads_group_id_fk.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7db21ceb51d74466d5c5644182f12c6d89c275df
--- /dev/null
+++ b/db/post_migrate/20241213150052_add_bulk_import_export_uploads_group_id_fk.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddBulkImportExportUploadsGroupIdFk < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+  disable_ddl_transaction!
+
+  def up
+    add_concurrent_foreign_key :bulk_import_export_uploads, :namespaces, column: :group_id, on_delete: :cascade
+  end
+
+  def down
+    with_lock_retries do
+      remove_foreign_key :bulk_import_export_uploads, column: :group_id
+    end
+  end
+end
diff --git a/db/post_migrate/20241213150053_add_bulk_import_export_uploads_group_id_trigger.rb b/db/post_migrate/20241213150053_add_bulk_import_export_uploads_group_id_trigger.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d64a0b21818b3f97886b2b298fa40235dc22ef09
--- /dev/null
+++ b/db/post_migrate/20241213150053_add_bulk_import_export_uploads_group_id_trigger.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class AddBulkImportExportUploadsGroupIdTrigger < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+
+  def up
+    install_sharding_key_assignment_trigger(
+      table: :bulk_import_export_uploads,
+      sharding_key: :group_id,
+      parent_table: :bulk_import_exports,
+      parent_sharding_key: :group_id,
+      foreign_key: :export_id
+    )
+  end
+
+  def down
+    remove_sharding_key_assignment_trigger(
+      table: :bulk_import_export_uploads,
+      sharding_key: :group_id,
+      parent_table: :bulk_import_exports,
+      parent_sharding_key: :group_id,
+      foreign_key: :export_id
+    )
+  end
+end
diff --git a/db/post_migrate/20241213150054_queue_backfill_bulk_import_export_uploads_group_id.rb b/db/post_migrate/20241213150054_queue_backfill_bulk_import_export_uploads_group_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..178b68d47297b8b9758693b248ba24e3fbbf3e81
--- /dev/null
+++ b/db/post_migrate/20241213150054_queue_backfill_bulk_import_export_uploads_group_id.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class QueueBackfillBulkImportExportUploadsGroupId < Gitlab::Database::Migration[2.2]
+  milestone '17.8'
+  restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
+
+  MIGRATION = "BackfillBulkImportExportUploadsGroupId"
+  DELAY_INTERVAL = 2.minutes
+  BATCH_SIZE = 1000
+  SUB_BATCH_SIZE = 100
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :bulk_import_export_uploads,
+      :id,
+      :group_id,
+      :bulk_import_exports,
+      :group_id,
+      :export_id,
+      job_interval: DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE
+    )
+  end
+
+  def down
+    delete_batched_background_migration(
+      MIGRATION,
+      :bulk_import_export_uploads,
+      :id,
+      [
+        :group_id,
+        :bulk_import_exports,
+        :group_id,
+        :export_id
+      ]
+    )
+  end
+end
diff --git a/db/schema_migrations/20241213150045 b/db/schema_migrations/20241213150045
new file mode 100644
index 0000000000000000000000000000000000000000..f12ba077073f17bedc4ce7740dcf3b9ff68e7a29
--- /dev/null
+++ b/db/schema_migrations/20241213150045
@@ -0,0 +1 @@
+1f05ebd14030efcc79a88a09a16c954d30f30032fce39068e23e8d9bf45b5ba7
\ No newline at end of file
diff --git a/db/schema_migrations/20241213150046 b/db/schema_migrations/20241213150046
new file mode 100644
index 0000000000000000000000000000000000000000..e305e9905481e93aa3527b7a1e7fca80ebadf622
--- /dev/null
+++ b/db/schema_migrations/20241213150046
@@ -0,0 +1 @@
+94d04e41dd8d681dea88a6828bf4f27c5812938dbf4436ae5ad81478b1c23fc4
\ No newline at end of file
diff --git a/db/schema_migrations/20241213150047 b/db/schema_migrations/20241213150047
new file mode 100644
index 0000000000000000000000000000000000000000..bfebf6f517e3e7510427da58f5402bff56ce7651
--- /dev/null
+++ b/db/schema_migrations/20241213150047
@@ -0,0 +1 @@
+cd31480390b905bba738eef4ac28e1fb392881a3097f6c69fa427dc85b7bc93a
\ No newline at end of file
diff --git a/db/schema_migrations/20241213150048 b/db/schema_migrations/20241213150048
new file mode 100644
index 0000000000000000000000000000000000000000..42d08b800bf6016e35cdb327349a5c7b9c66a755
--- /dev/null
+++ b/db/schema_migrations/20241213150048
@@ -0,0 +1 @@
+8c3064d90d9fc6cf33aa8685c634ff8c37934453075870b151a372f09aee8ee4
\ No newline at end of file
diff --git a/db/schema_migrations/20241213150049 b/db/schema_migrations/20241213150049
new file mode 100644
index 0000000000000000000000000000000000000000..2a0be66c0c21301f8053ac18096f012d0c9716a7
--- /dev/null
+++ b/db/schema_migrations/20241213150049
@@ -0,0 +1 @@
+c343e40451fe18fd57ce80a450a79bd8e7fb4d4e2b4166bcd260835d2dfa7579
\ No newline at end of file
diff --git a/db/schema_migrations/20241213150050 b/db/schema_migrations/20241213150050
new file mode 100644
index 0000000000000000000000000000000000000000..c974c77db0dd9806ccff28d9fd535f7aff862c9d
--- /dev/null
+++ b/db/schema_migrations/20241213150050
@@ -0,0 +1 @@
+7baaad2cc55cc1922708e1cf5cd0bcf465e4fe34f2d067e555966aa8c1a62107
\ No newline at end of file
diff --git a/db/schema_migrations/20241213150051 b/db/schema_migrations/20241213150051
new file mode 100644
index 0000000000000000000000000000000000000000..8cb7a269fc661355a6ad498349b7791365fa1126
--- /dev/null
+++ b/db/schema_migrations/20241213150051
@@ -0,0 +1 @@
+d93e4a954c0ca17c77f713fc4548fd9e18a249b1e3a63ba84f3670b6060ee638
\ No newline at end of file
diff --git a/db/schema_migrations/20241213150052 b/db/schema_migrations/20241213150052
new file mode 100644
index 0000000000000000000000000000000000000000..5e73567ce10e73e8ef1002aeed60b30f69a1b028
--- /dev/null
+++ b/db/schema_migrations/20241213150052
@@ -0,0 +1 @@
+837067ba8e1b2d7d55caf3658f76e4c18d23a365a1817279ec2cabc95ceebbb6
\ No newline at end of file
diff --git a/db/schema_migrations/20241213150053 b/db/schema_migrations/20241213150053
new file mode 100644
index 0000000000000000000000000000000000000000..c215bb10c63e24e8e6816f0fae876e099063cfba
--- /dev/null
+++ b/db/schema_migrations/20241213150053
@@ -0,0 +1 @@
+4b156e2d2d5ac4bb2bdb45e1220f7791d659eec1564b54d5dfda2b91f2863d00
\ No newline at end of file
diff --git a/db/schema_migrations/20241213150054 b/db/schema_migrations/20241213150054
new file mode 100644
index 0000000000000000000000000000000000000000..9937e853fec753c651c4561687d39784fbc89f21
--- /dev/null
+++ b/db/schema_migrations/20241213150054
@@ -0,0 +1 @@
+9bfe6e1f2ab40cf4e182d87a1d769c7ac377246f51d11b3f0f569dfa937035f9
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 2b7520aaaf419107545e938668ecf78e50249c27..3dd41fa740d5da581aa9bac3b6093abbbc207d67 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -1111,6 +1111,22 @@ RETURN NEW;
 END
 $$;
 
+CREATE FUNCTION trigger_0d96daa4d734() RETURNS trigger
+    LANGUAGE plpgsql
+    AS $$
+BEGIN
+IF NEW."group_id" IS NULL THEN
+  SELECT "group_id"
+  INTO NEW."group_id"
+  FROM "bulk_import_exports"
+  WHERE "bulk_import_exports"."id" = NEW."export_id";
+END IF;
+
+RETURN NEW;
+
+END
+$$;
+
 CREATE FUNCTION trigger_0da002390fdc() RETURNS trigger
     LANGUAGE plpgsql
     AS $$
@@ -1801,6 +1817,22 @@ RETURN NEW;
 END
 $$;
 
+CREATE FUNCTION trigger_4cc5c3ac4d7f() RETURNS trigger
+    LANGUAGE plpgsql
+    AS $$
+BEGIN
+IF NEW."project_id" IS NULL THEN
+  SELECT "project_id"
+  INTO NEW."project_id"
+  FROM "bulk_import_exports"
+  WHERE "bulk_import_exports"."id" = NEW."export_id";
+END IF;
+
+RETURN NEW;
+
+END
+$$;
+
 CREATE FUNCTION trigger_54707c384ad7() RETURNS trigger
     LANGUAGE plpgsql
     AS $$
@@ -8725,6 +8757,8 @@ CREATE TABLE bulk_import_export_uploads (
     updated_at timestamp with time zone NOT NULL,
     export_file text,
     batch_id bigint,
+    project_id bigint,
+    group_id bigint,
     CONSTRAINT check_5add76239d CHECK ((char_length(export_file) <= 255))
 );
 
@@ -29644,6 +29678,10 @@ CREATE INDEX index_bulk_import_entities_on_project_id ON bulk_import_entities US
 
 CREATE INDEX index_bulk_import_export_uploads_on_export_id ON bulk_import_export_uploads USING btree (export_id);
 
+CREATE INDEX index_bulk_import_export_uploads_on_group_id ON bulk_import_export_uploads USING btree (group_id);
+
+CREATE INDEX index_bulk_import_export_uploads_on_project_id ON bulk_import_export_uploads USING btree (project_id);
+
 CREATE INDEX index_bulk_import_exports_on_group_id ON bulk_import_exports USING btree (group_id);
 
 CREATE INDEX index_bulk_import_exports_on_project_id ON bulk_import_exports USING btree (project_id);
@@ -35710,6 +35748,8 @@ CREATE TRIGGER trigger_0aea02e5a699 BEFORE INSERT OR UPDATE ON protected_branch_
 
 CREATE TRIGGER trigger_0c326daf67cf BEFORE INSERT OR UPDATE ON analytics_cycle_analytics_value_stream_settings FOR EACH ROW EXECUTE FUNCTION trigger_0c326daf67cf();
 
+CREATE TRIGGER trigger_0d96daa4d734 BEFORE INSERT OR UPDATE ON bulk_import_export_uploads FOR EACH ROW EXECUTE FUNCTION trigger_0d96daa4d734();
+
 CREATE TRIGGER trigger_0da002390fdc BEFORE INSERT OR UPDATE ON operations_feature_flags_issues FOR EACH ROW EXECUTE FUNCTION trigger_0da002390fdc();
 
 CREATE TRIGGER trigger_0e13f214e504 BEFORE INSERT OR UPDATE ON merge_request_assignment_events FOR EACH ROW EXECUTE FUNCTION trigger_0e13f214e504();
@@ -35794,6 +35834,8 @@ CREATE TRIGGER trigger_4ad9a52a6614 BEFORE INSERT OR UPDATE ON sbom_occurrences_
 
 CREATE TRIGGER trigger_4b43790d717f BEFORE INSERT OR UPDATE ON protected_environment_approval_rules FOR EACH ROW EXECUTE FUNCTION trigger_4b43790d717f();
 
+CREATE TRIGGER trigger_4cc5c3ac4d7f BEFORE INSERT OR UPDATE ON bulk_import_export_uploads FOR EACH ROW EXECUTE FUNCTION trigger_4cc5c3ac4d7f();
+
 CREATE TRIGGER trigger_54707c384ad7 BEFORE INSERT OR UPDATE ON security_orchestration_policy_rule_schedules FOR EACH ROW EXECUTE FUNCTION trigger_54707c384ad7();
 
 CREATE TRIGGER trigger_56d49f4ed623 BEFORE INSERT OR UPDATE ON workspace_variables FOR EACH ROW EXECUTE FUNCTION trigger_56d49f4ed623();
@@ -36279,6 +36321,9 @@ ALTER TABLE ONLY alert_management_alerts
 ALTER TABLE ONLY design_management_designs
     ADD CONSTRAINT fk_239cd63678 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY bulk_import_export_uploads
+    ADD CONSTRAINT fk_23e0e92313 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY audit_events_streaming_http_instance_namespace_filters
     ADD CONSTRAINT fk_23f3ab7df0 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
 
@@ -36864,6 +36909,9 @@ ALTER TABLE ONLY sent_notifications
 ALTER TABLE ONLY labels
     ADD CONSTRAINT fk_7de4989a69 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
 
+ALTER TABLE ONLY bulk_import_export_uploads
+    ADD CONSTRAINT fk_7e03e410b4 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
 ALTER TABLE ONLY merge_requests
     ADD CONSTRAINT fk_7e85395a64 FOREIGN KEY (sprint_id) REFERENCES sprints(id) ON DELETE SET NULL;
 
diff --git a/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_group_id.rb b/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_group_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..83496ed41e4b280a6f9444d416da9d0321517c1a
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_group_id.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    class BackfillBulkImportExportUploadsGroupId < BackfillDesiredShardingKeyJob
+      operation_name :backfill_bulk_import_export_uploads_group_id
+      feature_category :importers
+    end
+  end
+end
diff --git a/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_project_id.rb b/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_project_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b0ca868f8de483a64041adb8e660fd0788d7da88
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_project_id.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    class BackfillBulkImportExportUploadsProjectId < BackfillDesiredShardingKeyJob
+      operation_name :backfill_bulk_import_export_uploads_project_id
+      feature_category :importers
+    end
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_group_id_spec.rb b/spec/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_group_id_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3cb9e124462ffa8d326b99190974ba3935966622
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_group_id_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillBulkImportExportUploadsGroupId,
+  feature_category: :importers,
+  schema: 20241213150050 do
+  include_examples 'desired sharding key backfill job' do
+    let(:batch_table) { :bulk_import_export_uploads }
+    let(:backfill_column) { :group_id }
+    let(:backfill_via_table) { :bulk_import_exports }
+    let(:backfill_via_column) { :group_id }
+    let(:backfill_via_foreign_key) { :export_id }
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_project_id_spec.rb b/spec/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_project_id_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..965f9f26084ab17e11e7412b84874073ceb94203
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_bulk_import_export_uploads_project_id_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillBulkImportExportUploadsProjectId,
+  feature_category: :importers,
+  schema: 20241213150045 do
+  include_examples 'desired sharding key backfill job' do
+    let(:batch_table) { :bulk_import_export_uploads }
+    let(:backfill_column) { :project_id }
+    let(:backfill_via_table) { :bulk_import_exports }
+    let(:backfill_via_column) { :project_id }
+    let(:backfill_via_foreign_key) { :export_id }
+  end
+end
diff --git a/spec/migrations/20241213150049_queue_backfill_bulk_import_export_uploads_project_id_spec.rb b/spec/migrations/20241213150049_queue_backfill_bulk_import_export_uploads_project_id_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f94138d003ce0651d618e0c487977f0f5a465231
--- /dev/null
+++ b/spec/migrations/20241213150049_queue_backfill_bulk_import_export_uploads_project_id_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillBulkImportExportUploadsProjectId, feature_category: :importers do
+  let!(:batched_migration) { described_class::MIGRATION }
+
+  it 'schedules a new batched migration' do
+    reversible_migration do |migration|
+      migration.before -> {
+        expect(batched_migration).not_to have_scheduled_batched_migration
+      }
+
+      migration.after -> {
+        expect(batched_migration).to have_scheduled_batched_migration(
+          table_name: :bulk_import_export_uploads,
+          column_name: :id,
+          interval: described_class::DELAY_INTERVAL,
+          batch_size: described_class::BATCH_SIZE,
+          sub_batch_size: described_class::SUB_BATCH_SIZE,
+          gitlab_schema: :gitlab_main_cell,
+          job_arguments: [
+            :project_id,
+            :bulk_import_exports,
+            :project_id,
+            :export_id
+          ]
+        )
+      }
+    end
+  end
+end
diff --git a/spec/migrations/20241213150054_queue_backfill_bulk_import_export_uploads_group_id_spec.rb b/spec/migrations/20241213150054_queue_backfill_bulk_import_export_uploads_group_id_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..887a818d2e905d885b0da78da3a07554b6e27db2
--- /dev/null
+++ b/spec/migrations/20241213150054_queue_backfill_bulk_import_export_uploads_group_id_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillBulkImportExportUploadsGroupId, feature_category: :importers do
+  let!(:batched_migration) { described_class::MIGRATION }
+
+  it 'schedules a new batched migration' do
+    reversible_migration do |migration|
+      migration.before -> {
+        expect(batched_migration).not_to have_scheduled_batched_migration
+      }
+
+      migration.after -> {
+        expect(batched_migration).to have_scheduled_batched_migration(
+          table_name: :bulk_import_export_uploads,
+          column_name: :id,
+          interval: described_class::DELAY_INTERVAL,
+          batch_size: described_class::BATCH_SIZE,
+          sub_batch_size: described_class::SUB_BATCH_SIZE,
+          gitlab_schema: :gitlab_main_cell,
+          job_arguments: [
+            :group_id,
+            :bulk_import_exports,
+            :group_id,
+            :export_id
+          ]
+        )
+      }
+    end
+  end
+end