diff --git a/ee/lib/gitlab/license_scanning/package_licenses.rb b/ee/lib/gitlab/license_scanning/package_licenses.rb
index d6f64c4aebcf870c9ef38fb393bb6175421414c2..6a4bcfe0fc6feffe73e9810e36648de2b9139a27 100644
--- a/ee/lib/gitlab/license_scanning/package_licenses.rb
+++ b/ee/lib/gitlab/license_scanning/package_licenses.rb
@@ -4,6 +4,7 @@ module Gitlab
   module LicenseScanning
     class PackageLicenses
       include Gitlab::InternalEventsTracking
+      include Gitlab::Utils::StrongMemoize
 
       BATCH_SIZE = 700
       UNKNOWN_LICENSE = {
@@ -136,7 +137,7 @@ def add_components_without_licenses(components_without_licenses)
 
         packages_for_batch.each do |package|
           requested_data_for_package(package).each do |component|
-            license_ids = package.license_ids_for(version: component[:version])
+            license_ids = license_ids_for(package, component[:version])
 
             next if license_ids.empty?
 
@@ -150,6 +151,12 @@ def add_components_without_licenses(components_without_licenses)
         end
       end
 
+      def license_ids_for(package, version)
+        strong_memoize_with(:license_ids_for, package, version) do
+          package.license_ids_for(version: version)
+        end
+      end
+
       def requested_data_for_package(package)
         component_data[component_data_key(name: package.name, purl_type: package.purl_type)]
       end
diff --git a/ee/spec/lib/gitlab/license_scanning/package_licenses_spec.rb b/ee/spec/lib/gitlab/license_scanning/package_licenses_spec.rb
index 5d3aacd1717741dcb410a21274e25f613856a479..4badd86cd20fc04b5b2ab9b2c56fa16daaa6283c 100644
--- a/ee/spec/lib/gitlab/license_scanning/package_licenses_spec.rb
+++ b/ee/spec/lib/gitlab/license_scanning/package_licenses_spec.rb
@@ -729,5 +729,54 @@
         end
       end
     end
+
+    context 'when processing identical components' do
+      let_it_be(:components_to_fetch) do
+        [
+          Hashie::Mash.new({ name: "beego", purl_type: "golang", version: "v1.10.0", path: nil }),
+          Hashie::Mash.new({ name: "beego", purl_type: "golang", version: "v1.10.0", path: nil }),
+          Hashie::Mash.new({ name: "camelcase", purl_type: "npm", version: "1.2.1", path: "" }),
+          Hashie::Mash.new({ name: "camelcase", purl_type: "npm", version: "4.1.0", path: "package-lock.json" }),
+          Hashie::Mash.new({ name: "cliui", purl_type: "npm", version: "2.1.0", path: "package-lock.json" }),
+          Hashie::Mash.new({ name: "cliui", purl_type: "npm", version: "2.1.0", path: "package-lock.json" }),
+          Hashie::Mash.new({ name: "cliui", purl_type: "golang", version: "2.1.0", path: "package-lock.json" }),
+          Hashie::Mash.new({ name: "cliui", purl_type: "golang", version: "2.1.1", path: "package-lock.json" })
+        ]
+      end
+
+      let(:package1) do
+        instance_double(PackageMetadata::Package, name: "beego", purl_type: "golang",
+          license_ids_for: [1])
+      end
+
+      let(:package2) do
+        instance_double(PackageMetadata::Package, name: "camelcase", purl_type: "npm",
+          license_ids_for: [1])
+      end
+
+      let(:package3) do
+        instance_double(PackageMetadata::Package, name: "cliui", purl_type: "npm",
+          license_ids_for: [1])
+      end
+
+      let(:package4) do
+        instance_double(PackageMetadata::Package, name: "cliui", purl_type: "golang",
+          license_ids_for: [1])
+      end
+
+      it 'only calls the model once to get licenses for a package' do
+        expect(PackageMetadata::Package)
+          .to receive(:packages_for)
+          .with(components: components_to_fetch)
+          .and_return([package1, package2, package3, package4])
+
+        fetch
+
+        expect(package1).to have_received(:license_ids_for).exactly(1).times
+        expect(package2).to have_received(:license_ids_for).exactly(2).times
+        expect(package3).to have_received(:license_ids_for).exactly(1).times
+        expect(package4).to have_received(:license_ids_for).exactly(2).times
+      end
+    end
   end
 end