diff --git a/db/docs/batched_background_migrations/backfill_default_organization_users.yml b/db/docs/batched_background_migrations/backfill_default_organization_users.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e22af38e1c43f0f23d0255b8d0149fd7fd1e5ac1
--- /dev/null
+++ b/db/docs/batched_background_migrations/backfill_default_organization_users.yml
@@ -0,0 +1,10 @@
+---
+migration_job_name: BackfillDefaultOrganizationUsers
+description: Populates organization_users with regular users (non admins) to the default organization.
+feature_category: cell
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/144674
+milestone: '16.10'
+queued_migration_version: 20240213210124
+# Replace with the approximate date you think it's best to ensure the completion of this BBM.
+finalize_after: '2024-03-15'
+finalized_by: # version of the migration that finalized this BBM
diff --git a/db/post_migrate/20240213210124_queue_backfill_default_organization_users.rb b/db/post_migrate/20240213210124_queue_backfill_default_organization_users.rb
new file mode 100644
index 0000000000000000000000000000000000000000..35a9387a35fbb4ee0e9f092adb4d30239720327a
--- /dev/null
+++ b/db/post_migrate/20240213210124_queue_backfill_default_organization_users.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class QueueBackfillDefaultOrganizationUsers < Gitlab::Database::Migration[2.2]
+  milestone '16.10'
+
+  MIGRATION = "BackfillDefaultOrganizationUsers"
+  DELAY_INTERVAL = 2.minutes
+  BATCH_SIZE = 3_000
+  SUB_BATCH_SIZE = 250
+  MAX_BATCH_SIZE = 10_000
+
+  restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+  def up
+    queue_batched_background_migration(
+      MIGRATION,
+      :users,
+      :id,
+      job_interval: DELAY_INTERVAL,
+      batch_size: BATCH_SIZE,
+      sub_batch_size: SUB_BATCH_SIZE,
+      max_batch_size: MAX_BATCH_SIZE
+    )
+  end
+
+  def down
+    delete_batched_background_migration(MIGRATION, :users, :id, [])
+  end
+end
diff --git a/db/schema_migrations/20240213210124 b/db/schema_migrations/20240213210124
new file mode 100644
index 0000000000000000000000000000000000000000..946ee93f61202792e5d1592e16ba022086f4ef55
--- /dev/null
+++ b/db/schema_migrations/20240213210124
@@ -0,0 +1 @@
+71f7ea5193599d6aabe52d2816505628d25f71f3ea7faf4560e7e53e1bf6c067
\ No newline at end of file
diff --git a/lib/gitlab/background_migration/backfill_default_organization_users.rb b/lib/gitlab/background_migration/backfill_default_organization_users.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bd51ce52e49cc4fe84d3f39a4a824bb8b1282ab8
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_default_organization_users.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Gitlab
+  module BackgroundMigration
+    class BackfillDefaultOrganizationUsers < BatchedMigrationJob
+      operation_name :backfill_default_organization_users # This is used as the key on collecting metrics
+      scope_to ->(relation) { relation.where(admin: false) } # true handled in BackfillDefaultOrganizationOwnersAgain
+      feature_category :cell
+
+      DEFAULT_ACCESS_LEVEL = 10
+      DEFAULT_ORGANIZATION_ID = 1
+
+      module Organizations
+        class OrganizationUser < ApplicationRecord
+          self.table_name = 'organization_users'
+          self.inheritance_column = :_type_disabled
+        end
+      end
+
+      def perform
+        each_sub_batch do |sub_batch|
+          organization_users_attributes = sub_batch.select(:id).map do |user|
+            {
+              user_id: user.id,
+              organization_id: DEFAULT_ORGANIZATION_ID,
+              access_level: DEFAULT_ACCESS_LEVEL
+            }
+          end
+
+          Organizations::OrganizationUser.upsert_all(
+            organization_users_attributes,
+            returning: false,
+            unique_by: [:organization_id, :user_id]
+          )
+        end
+      end
+    end
+  end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_default_organization_users_spec.rb b/spec/lib/gitlab/background_migration/backfill_default_organization_users_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b0f67f4f8e1963fa0e990fd8cef660444441f0b2
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_default_organization_users_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillDefaultOrganizationUsers, feature_category: :cell do
+  let(:organization_users) { table(:organization_users) }
+  let(:users) { table(:users) }
+
+  let!(:first_user) { users.create!(name: 'first', email: 'first_user@example.com', projects_limit: 1) }
+  let!(:last_user) { users.create!(name: 'last', email: 'last_user@example.com', projects_limit: 1) }
+  let!(:admin) { users.create!(name: 'admin user', email: 'admin_user@example.com', projects_limit: 1, admin: true) }
+
+  subject(:migration) do
+    described_class.new(
+      start_id: first_user.id,
+      end_id: admin.id,
+      batch_table: :users,
+      batch_column: :id,
+      sub_batch_size: 100,
+      pause_ms: 0,
+      connection: ApplicationRecord.connection
+    )
+  end
+
+  describe '#perform' do
+    context 'with no entries for a regular user in organization_users' do
+      it 'adds regular users correctly with the default organization to organization_users' do
+        expect(organization_users.count).to eq(0)
+
+        expect { migration.perform }.to change { organization_users.count }.by(2)
+
+        expect(organization_user_as_regular_user_exists?(first_user.id)).to be(true)
+        expect(organization_user_as_regular_user_exists?(last_user.id)).to be(true)
+      end
+    end
+
+    context 'when user already exists in organization_users as an admin user' do
+      before do
+        organization_users.create!(
+          organization_id: Organizations::Organization::DEFAULT_ORGANIZATION_ID,
+          user_id: first_user.id,
+          access_level: Gitlab::Access::OWNER
+        )
+      end
+
+      it 'updates the organization_users entry to a regular user' do
+        expect(organization_users.count).to eq(1)
+
+        expect { migration.perform }.to change { organization_users.count }.by(1)
+
+        expect(organization_user_as_regular_user_exists?(first_user.id)).to be(true)
+        expect(organization_user_as_regular_user_exists?(last_user.id)).to be(true)
+      end
+    end
+  end
+
+  def organization_user_as_regular_user_exists?(user_id)
+    organization_users.exists?(
+      organization_id: Organizations::Organization::DEFAULT_ORGANIZATION_ID,
+      user_id: user_id,
+      access_level: Gitlab::Access::GUEST
+    )
+  end
+end
diff --git a/spec/migrations/20240213210124_queue_backfill_default_organization_users_spec.rb b/spec/migrations/20240213210124_queue_backfill_default_organization_users_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0ebcea6f4545691e819e98a3b2edd0bf31189b6d
--- /dev/null
+++ b/spec/migrations/20240213210124_queue_backfill_default_organization_users_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe QueueBackfillDefaultOrganizationUsers, feature_category: :cell 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: :users,
+          column_name: :id,
+          interval: described_class::DELAY_INTERVAL,
+          batch_size: described_class::BATCH_SIZE,
+          sub_batch_size: described_class::SUB_BATCH_SIZE,
+          max_batch_size: described_class::MAX_BATCH_SIZE
+        )
+      }
+    end
+  end
+end