diff --git a/db/post_migrate/20240122071840_ensure_backfill_for_ci_builds_integer_columns_is_finished.rb b/db/post_migrate/20240122071840_ensure_backfill_for_ci_builds_integer_columns_is_finished.rb
new file mode 100644
index 0000000000000000000000000000000000000000..874dcd0b640aa67b128b08e48a216679cb6302fc
--- /dev/null
+++ b/db/post_migrate/20240122071840_ensure_backfill_for_ci_builds_integer_columns_is_finished.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+class EnsureBackfillForCiBuildsIntegerColumnsIsFinished < Gitlab::Database::Migration[2.2]
+  include Gitlab::Database::MigrationHelpers::ConvertToBigint
+  milestone '16.9'
+
+  restrict_gitlab_migration gitlab_schema: :gitlab_ci
+  disable_ddl_transaction!
+
+  TABLE_NAME = :ci_builds
+  COLUMN_NAMES = %w[
+    auto_canceled_by_id
+    commit_id
+    erased_by_id
+    project_id
+    runner_id
+    trigger_request_id
+    upstream_pipeline_id
+    user_id
+  ]
+  BIGINT_COLUMN_NAMES = COLUMN_NAMES.map { |name| "#{name}_convert_to_bigint" }
+
+  def up
+    ensure_batched_background_migration_is_finished(
+      job_class_name: 'CopyColumnUsingBackgroundMigrationJob',
+      table_name: TABLE_NAME,
+      column_name: 'id',
+      job_arguments: [COLUMN_NAMES, BIGINT_COLUMN_NAMES]
+    )
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20240123071840_prepare_async_indexes_for_p_ci_builds_auto_canceled_by_id.rb b/db/post_migrate/20240123071840_prepare_async_indexes_for_p_ci_builds_auto_canceled_by_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d894d29e7219299da5ee836beb4b2cfd2ae431dd
--- /dev/null
+++ b/db/post_migrate/20240123071840_prepare_async_indexes_for_p_ci_builds_auto_canceled_by_id.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class PrepareAsyncIndexesForPCiBuildsAutoCanceledById < Gitlab::Database::Migration[2.2]
+  include Gitlab::Database::PartitioningMigrationHelpers
+
+  milestone '16.9'
+  disable_ddl_transaction!
+
+  INDEX_NAME = "p_ci_builds_auto_canceled_by_id_bigint_idx"
+  TABLE_NAME = :p_ci_builds
+  COLUMN_NAME = :auto_canceled_by_id_convert_to_bigint
+  WHERE_CLAUSE = "auto_canceled_by_id_convert_to_bigint IS NOT NULL"
+
+  def up
+    Gitlab::Database::PostgresPartitionedTable.each_partition(TABLE_NAME) do |partition|
+      index_name = generated_index_name(partition.identifier, INDEX_NAME)
+      prepare_async_index partition.identifier, COLUMN_NAME, name: index_name, where: WHERE_CLAUSE
+    end
+  end
+
+  def down
+    Gitlab::Database::PostgresPartitionedTable.each_partition(TABLE_NAME) do |partition|
+      index_name = generated_index_name(partition.identifier, INDEX_NAME)
+      unprepare_async_index partition.identifier, COLUMN_NAME, name: index_name, where: WHERE_CLAUSE
+    end
+  end
+end
diff --git a/db/post_migrate/20240124081840_prepare_async_indexes_for_p_ci_builds_commit_id_part1.rb b/db/post_migrate/20240124081840_prepare_async_indexes_for_p_ci_builds_commit_id_part1.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a6d2ef157a2a75854a1dd80729618cfd9297fe11
--- /dev/null
+++ b/db/post_migrate/20240124081840_prepare_async_indexes_for_p_ci_builds_commit_id_part1.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+class PrepareAsyncIndexesForPCiBuildsCommitIdPart1 < Gitlab::Database::Migration[2.2]
+  include Gitlab::Database::PartitioningMigrationHelpers
+
+  milestone '16.9'
+  disable_ddl_transaction!
+
+  INDEXES = [
+    [[:commit_id_convert_to_bigint, :status, :type], "p_ci_builds_commit_id_bigint_status_type_idx"],
+    [[:commit_id_convert_to_bigint, :type, :name, :ref], "p_ci_builds_commit_id_bigint_type_name_ref_idx"]
+  ]
+  TABLE_NAME = :p_ci_builds
+
+  def up
+    Gitlab::Database::PostgresPartitionedTable.each_partition(TABLE_NAME) do |partition|
+      INDEXES.each do |columns, routing_table_index_name|
+        index_name = generated_index_name(partition.identifier, routing_table_index_name)
+        prepare_async_index partition.identifier, columns, name: index_name
+      end
+    end
+  end
+
+  def down
+    Gitlab::Database::PostgresPartitionedTable.each_partition(TABLE_NAME) do |partition|
+      INDEXES.each do |columns, routing_table_index_name|
+        index_name = generated_index_name(partition.identifier, routing_table_index_name)
+        unprepare_async_index partition.identifier, columns, name: index_name
+      end
+    end
+  end
+end
diff --git a/db/schema_migrations/20240122071840 b/db/schema_migrations/20240122071840
new file mode 100644
index 0000000000000000000000000000000000000000..b3363bc4b78db5a4d15d083ffb62d8313c13ef78
--- /dev/null
+++ b/db/schema_migrations/20240122071840
@@ -0,0 +1 @@
+a404dcf1d57886af351b696f8cbc451e7e81d69618a6bd3c30e1676a99172ca6
\ No newline at end of file
diff --git a/db/schema_migrations/20240123071840 b/db/schema_migrations/20240123071840
new file mode 100644
index 0000000000000000000000000000000000000000..e68e60a9ce85a134c64a2bd0b5ec74b74d5e2612
--- /dev/null
+++ b/db/schema_migrations/20240123071840
@@ -0,0 +1 @@
+3feac709d7c1e6d911068d096e876fcbdace5c3e47036a3c8d9bb347a4d6f4ba
\ No newline at end of file
diff --git a/db/schema_migrations/20240124081840 b/db/schema_migrations/20240124081840
new file mode 100644
index 0000000000000000000000000000000000000000..608c0f2ed712ce4ef66ed02f804623f1ec9da1c8
--- /dev/null
+++ b/db/schema_migrations/20240124081840
@@ -0,0 +1 @@
+93164c045f7581f7dbcd606f2217514344bf2fdb72a6ece05241214e7a7f3c9d
\ No newline at end of file