diff --git a/ee/app/assets/javascripts/usage_quotas/storage/components/namespace_storage_app.stories.js b/ee/app/assets/javascripts/usage_quotas/storage/components/namespace_storage_app.stories.js
index 1dfe02c6d9d73ed8b6ba9a864166352379698bb1..db66730a03a155330396606c4b61f6912ae9db40 100644
--- a/ee/app/assets/javascripts/usage_quotas/storage/components/namespace_storage_app.stories.js
+++ b/ee/app/assets/javascripts/usage_quotas/storage/components/namespace_storage_app.stories.js
@@ -86,6 +86,18 @@ export const SaasWithProjectLimits = {
   }),
 };
 
+export const SaasWithNoLimits = {
+  render: createTemplate({
+    provide: {
+      enforcementType: 'project_repository_limit',
+      isUsingNamespaceEnforcement: false,
+      isUsingProjectEnforcement: true,
+      totalRepositorySizeExcess: 0,
+      namespacePlanStorageIncluded: 0,
+    },
+  }),
+};
+
 export const SaasWithProjectLimitsLoading = {
   render: (...args) => {
     const apolloProvider = createMockApollo([
diff --git a/ee/app/assets/javascripts/usage_quotas/storage/components/no_limits_purchased_storage_breakdown_card.vue b/ee/app/assets/javascripts/usage_quotas/storage/components/no_limits_purchased_storage_breakdown_card.vue
new file mode 100644
index 0000000000000000000000000000000000000000..3da32d872705ded65eae4255b699c6354f0d53af
--- /dev/null
+++ b/ee/app/assets/javascripts/usage_quotas/storage/components/no_limits_purchased_storage_breakdown_card.vue
@@ -0,0 +1,72 @@
+<script>
+import { GlIcon, GlLink, GlCard, GlSkeletonLoader } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import { usageQuotasHelpPaths } from '~/usage_quotas/storage/constants';
+import { STORAGE_STATISTICS_USAGE_QUOTA_LEARN_MORE } from '../constants';
+import NumberToHumanSize from './number_to_human_size.vue';
+
+export default {
+  name: 'NoLimitsPurchasedStorageBreakdownCard',
+  components: {
+    GlIcon,
+    GlLink,
+    GlCard,
+    GlSkeletonLoader,
+    NumberToHumanSize,
+  },
+  props: {
+    loading: {
+      type: Boolean,
+      required: true,
+    },
+    purchasedStorage: {
+      type: Number,
+      required: true,
+    },
+  },
+  i18n: {
+    PROJECT_ENFORCEMENT_PURCHASE_CARD_TITLE: s__('UsageQuota|Purchased storage'),
+    STORAGE_STATISTICS_USAGE_QUOTA_LEARN_MORE,
+    PROJECT_ENFORCEMENT_PURCHASE_CARD_SUBTITLE: s__(
+      'UsageQuota|Any additional purchased storage will be displayed here.',
+    ),
+  },
+  usageQuotasHelpPaths,
+};
+</script>
+
+<template>
+  <gl-card>
+    <gl-skeleton-loader v-if="loading" :height="64">
+      <rect width="140" height="30" x="5" y="0" rx="4" />
+      <rect width="240" height="10" x="5" y="40" rx="4" />
+      <rect width="340" height="10" x="5" y="54" rx="4" />
+    </gl-skeleton-loader>
+    <div v-else>
+      <div class="gl-display-flex gl-align-items-center gl-justify-content-space-between">
+        <div class="gl-font-weight-bold" data-testid="purchased-storage-card-title">
+          {{ $options.i18n.PROJECT_ENFORCEMENT_PURCHASE_CARD_TITLE }}
+
+          <gl-link
+            :href="$options.usageQuotasHelpPaths.usageQuotasNamespaceStorageLimit"
+            target="_blank"
+            class="gl-ml-2"
+            :aria-label="$options.i18n.STORAGE_STATISTICS_USAGE_QUOTA_LEARN_MORE"
+          >
+            <gl-icon name="question-o" />
+          </gl-link>
+        </div>
+      </div>
+      <div class="gl-font-size-h-display gl-font-weight-bold gl-line-height-ratio-1000 gl-my-3">
+        <number-to-human-size
+          label-class="gl-font-lg"
+          :value="Number(purchasedStorage)"
+          plain-zero
+          data-testid="storage-purchased"
+        />
+      </div>
+      <hr class="gl-my-4" />
+      <p>{{ $options.i18n.PROJECT_ENFORCEMENT_PURCHASE_CARD_SUBTITLE }}</p>
+    </div>
+  </gl-card>
+</template>
diff --git a/ee/app/assets/javascripts/usage_quotas/storage/components/storage_usage_statistics.vue b/ee/app/assets/javascripts/usage_quotas/storage/components/storage_usage_statistics.vue
index 5ae6527c7ec739699a93a885e54a8c60354bd89c..92f20ce72a3bf080d2900672c661fa96f1b6f2a5 100644
--- a/ee/app/assets/javascripts/usage_quotas/storage/components/storage_usage_statistics.vue
+++ b/ee/app/assets/javascripts/usage_quotas/storage/components/storage_usage_statistics.vue
@@ -10,6 +10,7 @@ import NamespaceLimitsTotalStorageAvailableBreakdownCard from './namespace_limit
 import StorageUsageOverviewCard from './storage_usage_overview_card.vue';
 import ProjectLimitsExcessStorageBreakdownCard from './project_limits_excess_storage_breakdown_card.vue';
 import NumberToHumanSize from './number_to_human_size.vue';
+import NoLimitsPurchasedStorageBreakdownCard from './no_limits_purchased_storage_breakdown_card.vue';
 
 export default {
   components: {
@@ -22,6 +23,7 @@ export default {
     StorageUsageOverviewCard,
     ProjectLimitsExcessStorageBreakdownCard,
     NumberToHumanSize,
+    NoLimitsPurchasedStorageBreakdownCard,
   },
   directives: {
     GlModalDirective,
@@ -82,6 +84,12 @@ export default {
     namespaceStorageOverviewSubtitle: NAMESPACE_STORAGE_OVERVIEW_SUBTITLE,
   },
   computed: {
+    isUsingProjectEnforcementWithLimits() {
+      return this.isUsingProjectEnforcement && this.namespacePlanStorageIncluded !== 0;
+    },
+    isUsingProjectEnforcementWithNoLimits() {
+      return this.isUsingProjectEnforcement && this.namespacePlanStorageIncluded === 0;
+    },
     totalStorage() {
       return this.namespacePlanStorageIncluded + this.additionalPurchasedStorageSize;
     },
@@ -174,14 +182,22 @@ export default {
       />
 
       <template v-if="namespacePlanName">
+        <no-limits-purchased-storage-breakdown-card
+          v-if="isUsingProjectEnforcementWithNoLimits"
+          :purchased-storage="additionalPurchasedStorageSize"
+          :limited-access-mode-enabled="shouldShowLimitedAccessModal"
+          :loading="loading"
+        />
+
         <project-limits-excess-storage-breakdown-card
-          v-if="isUsingProjectEnforcement"
+          v-else-if="isUsingProjectEnforcementWithLimits"
           :purchased-storage="additionalPurchasedStorageSize"
           :limited-access-mode-enabled="shouldShowLimitedAccessModal"
           :loading="loading"
         />
+
         <namespace-limits-total-storage-available-breakdown-card
-          v-else
+          v-else-if="isUsingNamespaceEnforcement"
           :included-storage="namespacePlanStorageIncluded"
           :purchased-storage="additionalPurchasedStorageSize"
           :total-storage="totalStorage"
diff --git a/ee/spec/features/groups/usage_quotas/storage_tab_spec.rb b/ee/spec/features/groups/usage_quotas/storage_tab_spec.rb
index e5cdfc12dc3dc3225dd95fc05ce548cd6b9d3c57..975147e541e5ea66c0f2a1828a0ec259a54596fa 100644
--- a/ee/spec/features/groups/usage_quotas/storage_tab_spec.rb
+++ b/ee/spec/features/groups/usage_quotas/storage_tab_spec.rb
@@ -112,6 +112,8 @@
       stub_signing_key
       stub_feature_flags(limited_access_modal: true)
       stub_subscription_permissions_data(group.id, can_add_seats: false)
+      enforce_namespace_storage_limit(group)
+      set_enforcement_limit(group, megabytes: 100)
 
       visit_usage_quotas_page('storage-quota-tab')
       wait_for_requests
diff --git a/ee/spec/frontend/usage_quotas/storage/components/no_limits_purchased_storage_breakdown_card_spec.js b/ee/spec/frontend/usage_quotas/storage/components/no_limits_purchased_storage_breakdown_card_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..aa414900fd07f5747d107bc471ea383f75e18dda
--- /dev/null
+++ b/ee/spec/frontend/usage_quotas/storage/components/no_limits_purchased_storage_breakdown_card_spec.js
@@ -0,0 +1,46 @@
+import { GlSkeletonLoader } from '@gitlab/ui';
+import NoLimitsPurchasedStorageBreakdownCard from 'ee/usage_quotas/storage/components/no_limits_purchased_storage_breakdown_card.vue';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
+import NumberToHumanSize from 'ee/usage_quotas/storage/components/number_to_human_size.vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+
+describe('NoLimitsPurchasedStorageBreakdownCard', () => {
+  /** @type { import('helpers/vue_test_utils_helper').ExtendedWrapper } */
+  let wrapper;
+
+  const defaultProps = {
+    purchasedStorage: 256,
+    loading: false,
+  };
+
+  const createComponent = ({ props = {} } = {}) => {
+    wrapper = shallowMountExtended(NoLimitsPurchasedStorageBreakdownCard, {
+      propsData: { ...defaultProps, ...props },
+      stubs: {
+        NumberToHumanSize,
+      },
+    });
+  };
+
+  const findPurchacedStorage = () => wrapper.findByTestId('storage-purchased');
+  const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
+
+  it('renders the purchaced storage value', () => {
+    createComponent();
+    expect(findPurchacedStorage().text()).toContain(
+      numberToHumanSize(defaultProps.purchasedStorage, 1),
+    );
+  });
+
+  describe('skeleton loader', () => {
+    it('renders skeleton loader when loading prop is true', () => {
+      createComponent({ props: { loading: true } });
+      expect(findSkeletonLoader().exists()).toBe(true);
+    });
+
+    it('does not render skeleton loader when loading prop is false', () => {
+      createComponent({ props: { loading: false } });
+      expect(findSkeletonLoader().exists()).toBe(false);
+    });
+  });
+});
diff --git a/ee/spec/frontend/usage_quotas/storage/components/storage_usage_statistics_spec.js b/ee/spec/frontend/usage_quotas/storage/components/storage_usage_statistics_spec.js
index 061b94ff97b3949751416a40ac774c9c9c896ba0..899b1751ea011f9817d37d4faef7eb1c849d749a 100644
--- a/ee/spec/frontend/usage_quotas/storage/components/storage_usage_statistics_spec.js
+++ b/ee/spec/frontend/usage_quotas/storage/components/storage_usage_statistics_spec.js
@@ -4,6 +4,7 @@ import { GlButton, GlLink, GlSprintf, GlProgressBar } from '@gitlab/ui';
 import StorageUsageOverviewCard from 'ee/usage_quotas/storage/components/storage_usage_overview_card.vue';
 import NamespaceLimitsStorageUsageOverviewCard from 'ee/usage_quotas/storage/components/namespace_limits_storage_usage_overview_card.vue';
 import NamespaceLimitsTotalStorageAvailableBreakdownCard from 'ee/usage_quotas/storage/components/namespace_limits_total_storage_available_breakdown_card.vue';
+import NoLimitsPurchasedStorageBreakdownCard from 'ee/usage_quotas/storage/components/no_limits_purchased_storage_breakdown_card.vue';
 import ProjectLimitsExcessStorageBreakdownCard from 'ee/usage_quotas/storage/components/project_limits_excess_storage_breakdown_card.vue';
 import NumberToHumanSize from 'ee/usage_quotas/storage/components/number_to_human_size.vue';
 import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -72,6 +73,8 @@ describe('StorageUsageStatistics', () => {
     wrapper.findComponent(NamespaceLimitsTotalStorageAvailableBreakdownCard);
   const findProjectLimitsExcessStorageBreakdownCard = () =>
     wrapper.findComponent(ProjectLimitsExcessStorageBreakdownCard);
+  const findNoLimitsPurchasedStorageBreakdownCard = () =>
+    wrapper.findComponent(NoLimitsPurchasedStorageBreakdownCard);
   const findOverviewSubtitle = () => wrapper.findByTestId('overview-subtitle');
   const findPurchaseButton = () => wrapper.findComponent(GlButton);
   const findLimitedAccessModal = () => wrapper.findComponent(LimitedAccessModal);
@@ -201,15 +204,26 @@ describe('StorageUsageStatistics', () => {
   });
 
   describe('NamespaceLimitsTotalStorageAvailableBreakdownCard', () => {
-    it('does not render NamespaceLimitsTotalStorageAvailableBreakdownCard when namespace is using project enforcement', () => {
+    it('does not render when the namespace is using project enforcement', () => {
       createComponent();
       expect(findNamespaceLimitsTotalStorageAvailableBreakdownCard().exists()).toBe(false);
     });
 
-    it('passes the correct props to NamespaceLimitsTotalStorageAvailableBreakdownCard when namespace is NOT using project enforcement', () => {
+    it('does not render if there is no plan information', () => {
+      createComponent({
+        provide: {
+          namespacePlanName: null,
+        },
+      });
+
+      expect(findNamespaceLimitsTotalStorageAvailableBreakdownCard().exists()).toBe(false);
+    });
+
+    it('passes correct props when the namespace is NOT using project enforcement', () => {
       createComponent({
         provide: {
           isUsingProjectEnforcement: false,
+          isUsingNamespaceEnforcement: true,
         },
       });
 
@@ -222,20 +236,45 @@ describe('StorageUsageStatistics', () => {
         loading: false,
       });
     });
+  });
 
-    it('does not render storage card if there is no plan information', () => {
+  describe('NoLimitsPurchasedStorageBreakdownCard', () => {
+    it('does not render when namespace is NOT using project enforcement', () => {
       createComponent({
         provide: {
-          namespacePlanName: null,
+          isUsingProjectEnforcement: false,
         },
       });
+      expect(findNoLimitsPurchasedStorageBreakdownCard().exists()).toBe(false);
+    });
 
-      expect(findNamespaceLimitsTotalStorageAvailableBreakdownCard().exists()).toBe(false);
+    it('does not render when namespace IS using project enforcement with limits', () => {
+      createComponent({
+        provide: {
+          isUsingProjectEnforcement: true,
+          namespacePlanStorageIncluded: 1,
+        },
+      });
+      expect(findNoLimitsPurchasedStorageBreakdownCard().exists()).toBe(false);
+    });
+
+    it('passes correct props when namespace IS using project enforcement', () => {
+      createComponent({
+        provide: {
+          isUsingProjectEnforcement: true,
+          namespacePlanStorageIncluded: 0,
+        },
+      });
+
+      expect(findNoLimitsPurchasedStorageBreakdownCard().props()).toEqual({
+        purchasedStorage: withRootStorageStatistics.additionalPurchasedStorageSize,
+        loading: false,
+      });
     });
   });
 
   describe('ProjectLimitsExcessStorageBreakdownCard', () => {
-    it('does not render ProjectLimitsExcessStorageBreakdownCard when namespace is NOT using project enforcement', () => {
+    it('does not render when the namespace is NOT using project enforcement', () => {
       createComponent({
         provide: {
           isUsingProjectEnforcement: false,
@@ -244,7 +283,17 @@ describe('StorageUsageStatistics', () => {
       expect(findProjectLimitsExcessStorageBreakdownCard().exists()).toBe(false);
     });
 
-    it('passes the correct props to ProjectLimitsExcessStorageBreakdownCard when namespace is using project enforcement', () => {
+    it('does not render when the namespace IS using project enforcement with no limits', () => {
+      createComponent({
+        provide: {
+          isUsingProjectEnforcement: true,
+          namespacePlanStorageIncluded: 0,
+        },
+      });
+      expect(findProjectLimitsExcessStorageBreakdownCard().exists()).toBe(false);
+    });
+
+    it('passes correct props when the namespace IS using project enforcement', () => {
       createComponent();
 
       expect(findProjectLimitsExcessStorageBreakdownCard().props()).toEqual({
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index dd1d5be8a11a52372936b0d1fd23b55b221c4153..92b0cb58e9d7b3e47f14814dfb097af6ce73c2d0 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -51401,6 +51401,9 @@ msgstr ""
 msgid "UsageQuota|%{storage_limit_link_start}A namespace storage limit%{link_end} will soon be enforced for the %{strong_start}%{namespace_name}%{strong_end} namespace. %{extra_message}"
 msgstr ""
 
+msgid "UsageQuota|Any additional purchased storage will be displayed here."
+msgstr ""
+
 msgid "UsageQuota|Audio samples, videos, datasets, and graphics."
 msgstr ""
 
@@ -51515,6 +51518,9 @@ msgstr ""
 msgid "UsageQuota|Projects under this namespace have %{planLimit} of storage."
 msgstr ""
 
+msgid "UsageQuota|Purchased storage"
+msgstr ""
+
 msgid "UsageQuota|Recalculate repository usage"
 msgstr ""