diff --git a/ee/app/models/gitlab_subscriptions/add_on_purchase.rb b/ee/app/models/gitlab_subscriptions/add_on_purchase.rb
index c832ac84e6144eb1ee5412c89dfc58df4816b2c5..0c209aee5a930ff84a386a96e1d28514af40e217 100644
--- a/ee/app/models/gitlab_subscriptions/add_on_purchase.rb
+++ b/ee/app/models/gitlab_subscriptions/add_on_purchase.rb
@@ -54,10 +54,8 @@ def expired?
     def delete_ineligible_user_assignments_in_batches!(batch_size: 50)
       deleted_assignments_count = 0
 
-      return deleted_assignments_count unless namespace.present?
-
       assigned_users.each_batch(of: batch_size) do |batch|
-        ineligible_user_ids = batch.pluck_user_ids.to_set - eligible_user_ids_for_assignment
+        ineligible_user_ids = filter_ineligible_assigned_user_ids(batch.pluck_user_ids.to_set)
 
         deleted_assignments_count += batch.for_user_ids(ineligible_user_ids).delete_all
 
@@ -75,10 +73,26 @@ def delete_ineligible_user_assignments_in_batches!(batch_size: 50)
 
     private
 
-    def eligible_user_ids_for_assignment
+    def filter_ineligible_assigned_user_ids(assigned_user_ids)
+      return assigned_user_ids - saas_eligible_user_ids if namespace
+
+      assigned_user_ids - self_managed_eligible_users_relation.where(id: assigned_user_ids).pluck(:id)
+    end
+
+    def saas_eligible_user_ids
       @eligible_user_ids ||= namespace.code_suggestions_eligible_user_ids
     end
 
+    def self_managed_eligible_users_relation
+      @self_managed_eligible_users_relation ||= GitlabSubscriptions::SelfManaged::AddOnEligibleUsersFinder.new(
+        add_on_type: add_on_type
+      ).execute
+    end
+
+    def add_on_type
+      add_on.name.to_sym
+    end
+
     def gitlab_com?
       ::Gitlab::CurrentSettings.should_check_namespace_plan?
     end
diff --git a/ee/spec/models/gitlab_subscriptions/add_on_purchase_spec.rb b/ee/spec/models/gitlab_subscriptions/add_on_purchase_spec.rb
index 1e878ad9713ca56d973cc3902e39aac28fabd44e..88276c600e43f86b3eefc31822e413b8dd2bc9f0 100644
--- a/ee/spec/models/gitlab_subscriptions/add_on_purchase_spec.rb
+++ b/ee/spec/models/gitlab_subscriptions/add_on_purchase_spec.rb
@@ -326,19 +326,19 @@
   describe '#delete_ineligible_user_assignments_in_batches!' do
     let(:add_on_purchase) { create(:gitlab_subscription_add_on_purchase) }
 
-    let_it_be(:user_1) { create(:user) }
-    let_it_be(:user_2) { create(:user) }
+    let_it_be(:eligible_user) { create(:user) }
+    let_it_be(:ineligible_user) { create(:user) }
 
     subject(:result) { add_on_purchase.delete_ineligible_user_assignments_in_batches! }
 
     context 'with assigned_users records' do
       before do
-        add_on_purchase.assigned_users.create!(user: user_1)
-        add_on_purchase.assigned_users.create!(user: user_2)
+        add_on_purchase.assigned_users.create!(user: eligible_user)
+        add_on_purchase.assigned_users.create!(user: ineligible_user)
       end
 
       it 'removes only ineligible user assignments' do
-        add_on_purchase.namespace.add_guest(user_1) # user_1 still eligible
+        add_on_purchase.namespace.add_guest(eligible_user)
 
         expect(add_on_purchase.reload.assigned_users.count).to eq(2)
 
@@ -346,7 +346,7 @@
           expect(result).to eq(1)
         end.to change { add_on_purchase.reload.assigned_users.count }.by(-1)
 
-        expect(add_on_purchase.reload.assigned_users.where(user: user_1).count).to eq(1)
+        expect(add_on_purchase.reload.assigned_users.where(user: eligible_user).count).to eq(1)
       end
 
       it 'accepts batch_size and deletes the assignments in batch' do
@@ -358,19 +358,19 @@
       end
 
       it 'expires the cache keys for the ineligible users', :use_clean_rails_redis_caching do
-        user_1_cache_key = format(User::CODE_SUGGESTIONS_ADD_ON_CACHE_KEY, user_id: user_1.id)
-        user_2_cache_key = format(User::CODE_SUGGESTIONS_ADD_ON_CACHE_KEY, user_id: user_2.id)
-        Rails.cache.write(user_1_cache_key, true, expires_in: 1.hour)
-        Rails.cache.write(user_2_cache_key, true, expires_in: 1.hour)
+        eligible_user_cache_key = format(User::CODE_SUGGESTIONS_ADD_ON_CACHE_KEY, user_id: eligible_user.id)
+        ineligible_user_cache_key = format(User::CODE_SUGGESTIONS_ADD_ON_CACHE_KEY, user_id: ineligible_user.id)
+        Rails.cache.write(eligible_user_cache_key, true, expires_in: 1.hour)
+        Rails.cache.write(ineligible_user_cache_key, true, expires_in: 1.hour)
 
-        add_on_purchase.namespace.add_guest(user_1) # user_1 still eligible
+        add_on_purchase.namespace.add_guest(eligible_user)
 
         expect(add_on_purchase.reload.assigned_users.count).to eq(2)
 
         expect { expect(result).to eq(1) }
           .to change { add_on_purchase.reload.assigned_users.count }.by(-1)
-          .and change { Rails.cache.read(user_2_cache_key) }.from(true).to(nil)
-          .and not_change { Rails.cache.read(user_1_cache_key) }
+          .and change { Rails.cache.read(ineligible_user_cache_key) }.from(true).to(nil)
+          .and not_change { Rails.cache.read(eligible_user_cache_key) }
       end
 
       context 'when the add_on_purchase has no namespace' do
@@ -378,20 +378,40 @@
           add_on_purchase.update_attribute(:namespace, nil)
         end
 
-        it { is_expected.to eq(0) }
+        context 'when all assigned users are eligible' do
+          it { is_expected.to eq(0) }
+        end
+
+        context 'when there are ineligible users' do
+          it 'removes only ineligible user assignments' do
+            ineligible_user.block!
+
+            expect(add_on_purchase.reload.assigned_users.count).to eq(2)
+
+            expect_next_instance_of(::GitlabSubscriptions::SelfManaged::AddOnEligibleUsersFinder) do |finder|
+              expect(finder).to receive(:execute).and_call_original
+            end
+
+            expect do
+              expect(result).to eq(1)
+            end.to change { add_on_purchase.reload.assigned_users.count }.by(-1)
+
+            expect(add_on_purchase.reload.assigned_users.where(user: eligible_user).count).to eq(1)
+          end
+        end
       end
     end
 
     context 'with no assigned_users records' do
       it { is_expected.to eq(0) }
-    end
 
-    context 'when add_on_purchase does not have namespace' do
-      before do
-        add_on_purchase.update!(namespace: nil)
-      end
+      context 'when add_on_purchase does not have namespace' do
+        before do
+          add_on_purchase.update!(namespace: nil)
+        end
 
-      it { is_expected.to eq(0) }
+        it { is_expected.to eq(0) }
+      end
     end
   end
 end