diff --git a/db/post_migrate/20240716182300_add_tmp_index_to_namespace_settings_on_new_user_signups_cap.rb b/db/post_migrate/20240716182300_add_tmp_index_to_namespace_settings_on_new_user_signups_cap.rb
new file mode 100644
index 0000000000000000000000000000000000000000..73fe4056f6386cd2b7bdf0fafb8851c278bde525
--- /dev/null
+++ b/db/post_migrate/20240716182300_add_tmp_index_to_namespace_settings_on_new_user_signups_cap.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddTmpIndexToNamespaceSettingsOnNewUserSignupsCap < Gitlab::Database::Migration[2.2]
+  disable_ddl_transaction!
+
+  milestone '17.3'
+
+  TABLE = :namespace_settings
+  COLUMN = :new_user_signups_cap
+  INDEX_NAME = 'tmp_index_namespace_settings_on_new_user_signups_cap'
+
+  def up
+    add_concurrent_index TABLE, COLUMN, name: INDEX_NAME, where: 'new_user_signups_cap IS NOT NULL'
+  end
+
+  def down
+    remove_concurrent_index_by_name TABLE, INDEX_NAME
+  end
+end
diff --git a/db/post_migrate/20240716182330_sync_namespace_settings_seat_control_with_user_cap.rb b/db/post_migrate/20240716182330_sync_namespace_settings_seat_control_with_user_cap.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2407c61556d48fdf5e91f269737e0a72e4605b14
--- /dev/null
+++ b/db/post_migrate/20240716182330_sync_namespace_settings_seat_control_with_user_cap.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class SyncNamespaceSettingsSeatControlWithUserCap < Gitlab::Database::Migration[2.2]
+  restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+  disable_ddl_transaction!
+
+  milestone '17.3'
+
+  def up
+    define_batchable_model('namespace_settings').where.not(new_user_signups_cap: nil).each_batch do |relation|
+      relation.update_all(seat_control: 1)
+    end
+  end
+
+  def down
+    # no-op
+  end
+end
diff --git a/db/post_migrate/20240716182400_remove_tmp_index_from_namespace_settings_on_new_user_signups_cap.rb b/db/post_migrate/20240716182400_remove_tmp_index_from_namespace_settings_on_new_user_signups_cap.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ceac3e3647cbdcd4effed86ca261c1dc8c1863b0
--- /dev/null
+++ b/db/post_migrate/20240716182400_remove_tmp_index_from_namespace_settings_on_new_user_signups_cap.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class RemoveTmpIndexFromNamespaceSettingsOnNewUserSignupsCap < Gitlab::Database::Migration[2.2]
+  disable_ddl_transaction!
+
+  milestone '17.3'
+
+  TABLE = :namespace_settings
+  COLUMN = :new_user_signups_cap
+  INDEX_NAME = 'tmp_index_namespace_settings_on_new_user_signups_cap'
+
+  def up
+    remove_concurrent_index_by_name TABLE, INDEX_NAME
+  end
+
+  def down
+    add_concurrent_index TABLE, COLUMN, name: INDEX_NAME, where: 'new_user_signups_cap IS NOT NULL'
+  end
+end
diff --git a/db/schema_migrations/20240716182300 b/db/schema_migrations/20240716182300
new file mode 100644
index 0000000000000000000000000000000000000000..becefeacf28a70b8ac0fa0e8dfc143d5c58a6964
--- /dev/null
+++ b/db/schema_migrations/20240716182300
@@ -0,0 +1 @@
+0bbf02a4cf3b620d0e4cdd180a6543d7fd160174f3bf3a9ae43f9b1000d4ce60
\ No newline at end of file
diff --git a/db/schema_migrations/20240716182330 b/db/schema_migrations/20240716182330
new file mode 100644
index 0000000000000000000000000000000000000000..6ed5b37a9026fbea4065d1221fb09d7784224a24
--- /dev/null
+++ b/db/schema_migrations/20240716182330
@@ -0,0 +1 @@
+7d3bd4c25d5e3adcf41f9b2821fff4e769841066b11d3f26ba96065377ec9b34
\ No newline at end of file
diff --git a/db/schema_migrations/20240716182400 b/db/schema_migrations/20240716182400
new file mode 100644
index 0000000000000000000000000000000000000000..fdeeb2861be3e78c06fb9eb8da96dc45751841f7
--- /dev/null
+++ b/db/schema_migrations/20240716182400
@@ -0,0 +1 @@
+be480d22843ca39035f8d6bf721d9b5922582e7aa0ba4e939b8a8a0994d059fc
\ No newline at end of file
diff --git a/spec/migrations/20240715183917_sync_namespace_settings_seat_control_with_user_cap_spec.rb b/spec/migrations/20240715183917_sync_namespace_settings_seat_control_with_user_cap_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..93792c4ad63e2946318dd61f3e256b76be9dc1f6
--- /dev/null
+++ b/spec/migrations/20240715183917_sync_namespace_settings_seat_control_with_user_cap_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SyncNamespaceSettingsSeatControlWithUserCap, feature_category: :consumables_cost_management do
+  let(:namespaces) { table(:namespaces) }
+  let(:namespace_settings) { table(:namespace_settings) }
+
+  it 'sets the value of seat_control to 1 where new_user_signups_cap has a value' do
+    namespace = namespaces.create!(name: 'MyNamespace', path: 'my-namespace')
+    settings = namespace_settings.create!(namespace_id: namespace.id, new_user_signups_cap: 10, seat_control: 0)
+
+    migrate!
+
+    expect(settings.reload.seat_control).to eq(1)
+  end
+
+  it 'does not change the value of seat_control where new_user_signups_cap is null' do
+    namespace = namespaces.create!(name: 'MyNamespace', path: 'my-namespace')
+    settings = namespace_settings.create!(namespace_id: namespace.id, new_user_signups_cap: nil, seat_control: 0)
+
+    migrate!
+
+    expect(settings.reload.seat_control).to eq(0)
+  end
+
+  it 'sets the value of seat_control for multiple rows' do
+    namespace_a = namespaces.create!(name: 'MyNamespaceA', path: 'my-namespace-a')
+    settings_a = namespace_settings.create!(namespace_id: namespace_a.id, new_user_signups_cap: 5, seat_control: 0)
+    namespace_b = namespaces.create!(name: 'MyNamespaceB', path: 'my-namespace-b')
+    settings_b = namespace_settings.create!(namespace_id: namespace_b.id, new_user_signups_cap: nil, seat_control: 0)
+    namespace_c = namespaces.create!(name: 'MyNamespaceC', path: 'my-namespace-c')
+    settings_c = namespace_settings.create!(namespace_id: namespace_c.id, new_user_signups_cap: 20, seat_control: 0)
+
+    migrate!
+
+    expect(settings_a.reload.seat_control).to eq(1)
+    expect(settings_b.reload.seat_control).to eq(0)
+    expect(settings_c.reload.seat_control).to eq(1)
+  end
+end