diff --git a/ee/app/mailers/ci_minutes_usage_mailer.rb b/ee/app/mailers/ci_minutes_usage_mailer.rb
index 4069ada35a36911c77dba9f3522aa292a8e8b310..51a28989968bd740988b50117e1504c25105b779 100644
--- a/ee/app/mailers/ci_minutes_usage_mailer.rb
+++ b/ee/app/mailers/ci_minutes_usage_mailer.rb
@@ -1,12 +1,16 @@
 # frozen_string_literal: true
 
 class CiMinutesUsageMailer < ApplicationMailer
+  helper EmailsHelper
+
+  layout 'mailer'
+
   def notify(namespace_name, recipients)
     @namespace_name = namespace_name
 
     mail(
       bcc: recipients,
-      subject: "GitLab CI Runner Minutes quota for #{namespace_name} has run out"
+      subject: "Action required: There are no remaining Pipeline minutes for #{namespace_name}"
     )
   end
 
@@ -16,8 +20,8 @@ def notify_limit(namespace_name, recipients, percentage_of_available_mins)
 
     mail(
       bcc: recipients,
-      subject: "GitLab CI Runner Minutes quota for #{namespace_name} has \
-                less than #{percentage_of_available_mins}% available"
+      subject: "Action required: Less than #{percentage_of_available_mins}% " \
+               "of Pipeline minutes remain for #{namespace_name}"
     )
   end
 end
diff --git a/ee/app/mailers/previews/ci_minutes_usage_mailer_preview.rb b/ee/app/mailers/previews/ci_minutes_usage_mailer_preview.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3d4b5537902868d1ac088da23e7cc7927fdb12f1
--- /dev/null
+++ b/ee/app/mailers/previews/ci_minutes_usage_mailer_preview.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class CiMinutesUsageMailerPreview < ActionMailer::Preview
+  def out_of_minutes
+    ::CiMinutesUsageMailer.notify('GROUP_NAME', %w(bob@example.com))
+  end
+
+  def limit_warning
+    ::CiMinutesUsageMailer.notify_limit('GROUP_NAME', %w(bob@example.com), 30)
+  end
+end
diff --git a/ee/app/services/ci/minutes/email_notification_service.rb b/ee/app/services/ci/minutes/email_notification_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ded134368d0b7935d5605580184a1050cd51c453
--- /dev/null
+++ b/ee/app/services/ci/minutes/email_notification_service.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Ci
+  module Minutes
+    class EmailNotificationService < ::BaseService
+      def execute
+        return unless ::Gitlab.com?
+        return unless namespace.shared_runners_minutes_limit_enabled?
+
+        notify_on_total_usage
+        notify_on_partial_usage
+      end
+
+      private
+
+      def recipients
+        namespace.user? ? [namespace.owner.email] : namespace.owners.pluck(:email) # rubocop:disable CodeReuse/ActiveRecord
+      end
+
+      def notify_on_total_usage
+        return unless namespace.shared_runners_minutes_used? && namespace.last_ci_minutes_notification_at.nil?
+
+        namespace.update_columns(last_ci_minutes_notification_at: Time.now)
+
+        CiMinutesUsageMailer.notify(namespace.name, recipients).deliver_later
+      end
+
+      def notify_on_partial_usage
+        return if namespace.shared_runners_minutes_used?
+        return if namespace.last_ci_minutes_usage_notification_level == current_alert_level
+        return if alert_levels.max < namespace.shared_runners_remaining_minutes_percent
+
+        namespace.update_columns(last_ci_minutes_usage_notification_level: current_alert_level)
+
+        CiMinutesUsageMailer.notify_limit(namespace.name, recipients, current_alert_level).deliver_later
+      end
+
+      def namespace
+        @namespace ||= project.shared_runners_limit_namespace
+      end
+
+      def alert_levels
+        @alert_levels ||= EE::Namespace::CI_USAGE_ALERT_LEVELS.sort
+      end
+
+      def current_alert_level
+        remaining_percent = namespace.shared_runners_remaining_minutes_percent
+
+        @current_alert_level ||= alert_levels.find { |level| level >= remaining_percent }
+      end
+    end
+  end
+end
diff --git a/ee/app/services/ci_minutes_usage_notify_service.rb b/ee/app/services/ci_minutes_usage_notify_service.rb
deleted file mode 100644
index 2f7c24d1cc537023d854fb8c5782e490d5e8189e..0000000000000000000000000000000000000000
--- a/ee/app/services/ci_minutes_usage_notify_service.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-# frozen_string_literal: true
-
-class CiMinutesUsageNotifyService < BaseService
-  def execute
-    return unless ::Gitlab.com?
-    return unless namespace.shared_runners_minutes_limit_enabled?
-
-    notify_on_total_usage
-    notify_on_partial_usage
-  end
-
-  private
-
-  def recipients
-    namespace.user? ? [namespace.owner.email] : namespace.owners.pluck(:email) # rubocop:disable CodeReuse/ActiveRecord
-  end
-
-  def notify_on_total_usage
-    return unless namespace.shared_runners_minutes_used? && namespace.last_ci_minutes_notification_at.nil?
-
-    namespace.update_columns(last_ci_minutes_notification_at: Time.now)
-
-    CiMinutesUsageMailer.notify(namespace.name, recipients).deliver_later
-  end
-
-  def notify_on_partial_usage
-    return if namespace.shared_runners_minutes_used?
-    return if namespace.last_ci_minutes_usage_notification_level == current_alert_level
-    return if alert_levels.max < namespace.shared_runners_remaining_minutes_percent
-
-    namespace.update_columns(last_ci_minutes_usage_notification_level: current_alert_level)
-
-    CiMinutesUsageMailer.notify_limit(namespace.name, recipients, current_alert_level).deliver_later
-  end
-
-  def namespace
-    @namespace ||= project.shared_runners_limit_namespace
-  end
-
-  def alert_levels
-    @alert_levels ||= EE::Namespace::CI_USAGE_ALERT_LEVELS.sort
-  end
-
-  def current_alert_level
-    remaining_percent = namespace.shared_runners_remaining_minutes_percent
-
-    @current_alert_level ||= alert_levels.find { |level| level >= remaining_percent }
-  end
-end
diff --git a/ee/app/views/ci_minutes_usage_mailer/notify.html.haml b/ee/app/views/ci_minutes_usage_mailer/notify.html.haml
index d5fd78c904ab682e6f66f7b91087bf148ba1d403..e65c5c323e6143abca2006d0a822ebb07aaf7bf5 100644
--- a/ee/app/views/ci_minutes_usage_mailer/notify.html.haml
+++ b/ee/app/views/ci_minutes_usage_mailer/notify.html.haml
@@ -1,6 +1,6 @@
 %p
-  This is an automated notification to let you know that your CI Runner Minutes quota for "#{@namespace_name}" has run out.
+  = _('%{name} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run.') % { name: @namespace_name }
 %p
-  Click #{link_to('here', EE::SUBSCRIPTIONS_PLANS_URL)} to purchase more minutes.
+  = _('We recommend that you buy more Pipeline minutes to resume normal service.')
 %p
-  If you need assistance, please contact #{link_to('GitLab support', EE::CUSTOMER_SUPPORT_URL)}.
+  #{link_to('Buy more Pipeline minutes →', EE::SUBSCRIPTIONS_MORE_MINUTES_URL)}
diff --git a/ee/app/views/ci_minutes_usage_mailer/notify.text.erb b/ee/app/views/ci_minutes_usage_mailer/notify.text.erb
index 9cd3ccabee62fa8b01e759a29116ea63382aabab..a64cdce76449152c073f77f96f843c9c67204832 100644
--- a/ee/app/views/ci_minutes_usage_mailer/notify.text.erb
+++ b/ee/app/views/ci_minutes_usage_mailer/notify.text.erb
@@ -1,5 +1,6 @@
-This is an automated notification to let you know that your CI Runner Minutes quota for "<%= @namespace_name %>" has run out.
+<%= _('%{name} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run.') % { name: @namespace_name } %>
 
-Please visit <%= EE::SUBSCRIPTIONS_PLANS_URL %> to purchase more minutes.
+<%= _('We recommend that you buy more Pipeline minutes to resume normal service.') %>
 
-If you need assistance, please contact GitLab support (<%= EE::CUSTOMER_SUPPORT_URL %>).
+
+Buy more Pipeline minutes → <%= EE::SUBSCRIPTIONS_MORE_MINUTES_URL %>
diff --git a/ee/app/views/ci_minutes_usage_mailer/notify_limit.html.haml b/ee/app/views/ci_minutes_usage_mailer/notify_limit.html.haml
index 96628d838dc6e8612b0ed43cda2ac7c27c1079b6..201762bb821262774fc6b4811c3f13e84a37c306 100644
--- a/ee/app/views/ci_minutes_usage_mailer/notify_limit.html.haml
+++ b/ee/app/views/ci_minutes_usage_mailer/notify_limit.html.haml
@@ -1,6 +1,6 @@
 %p
-  This is an automated notification to let you know that your CI Runner Minutes quota for "#{@namespace_name}" is below #{@percentage_of_available_mins}%.
+  = _('%{name} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run.') % { name: @namespace_name, percent: "#{@percentage_of_available_mins}%" }
 %p
-  Click #{link_to('here', EE::SUBSCRIPTIONS_PLANS_URL)} to purchase more minutes.
+  = _('We recommend that you buy more Pipeline minutes to avoid any interruption of service.')
 %p
-  If you need assistance, please contact #{link_to('GitLab support', EE::CUSTOMER_SUPPORT_URL)}.
+  #{link_to('Buy more Pipeline minutes →', EE::SUBSCRIPTIONS_MORE_MINUTES_URL)}
diff --git a/ee/app/views/ci_minutes_usage_mailer/notify_limit.text.erb b/ee/app/views/ci_minutes_usage_mailer/notify_limit.text.erb
index eaf96243a74167a73fedfd29c9b66b2c68a1dccf..0223c26d285308042370b1bba03519b8294abc53 100644
--- a/ee/app/views/ci_minutes_usage_mailer/notify_limit.text.erb
+++ b/ee/app/views/ci_minutes_usage_mailer/notify_limit.text.erb
@@ -1,6 +1,5 @@
-This is an automated notification to let you know that your CI Runner Minutes
-quota for "<%= @namespace_name %>" is below <%= @percentage_of_available_mins %>%.
+<%= _('%{name} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run.') % { name: @namespace_name, percent: "#{@percentage_of_available_mins}%" } %>
 
-Please visit <%= EE::SUBSCRIPTIONS_PLANS_URL %> to purchase more minutes.
+<%= _('We recommend that you buy more Pipeline minutes to avoid any interruption of service.') %>
 
-If you need assistance, please contact GitLab support (<%= EE::CUSTOMER_SUPPORT_URL %>).
+Buy more Pipeline minutes → <%= EE::SUBSCRIPTIONS_MORE_MINUTES_URL %>
diff --git a/ee/app/workers/ee/build_finished_worker.rb b/ee/app/workers/ee/build_finished_worker.rb
index ff75f4735fe1227891177aa8b6da22990b0b1f26..546a3a3596cd767d41d9700fbeb37b8646fe067b 100644
--- a/ee/app/workers/ee/build_finished_worker.rb
+++ b/ee/app/workers/ee/build_finished_worker.rb
@@ -6,7 +6,7 @@ def process_build(build)
       UpdateBuildMinutesService.new(build.project, nil).execute(build)
       # We need to use `reset` on `project` because their AR associations have been cached
       # and `Namespace#namespace_statistics` will return stale data.
-      CiMinutesUsageNotifyService.new(build.project.reset).execute
+      ::Ci::Minutes::EmailNotificationService.new(build.project.reset).execute
 
       StoreSecurityScansWorker.perform_async(build.id)
 
diff --git a/ee/changelogs/unreleased/214997-improve-the-you-re-running-out-of-ci-minutes-email-notification.yml b/ee/changelogs/unreleased/214997-improve-the-you-re-running-out-of-ci-minutes-email-notification.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6c646c6c666245c23b676eb0d3a4dec1c7cbf872
--- /dev/null
+++ b/ee/changelogs/unreleased/214997-improve-the-you-re-running-out-of-ci-minutes-email-notification.yml
@@ -0,0 +1,5 @@
+---
+title: Improve the running out of CI minutes email notification
+merge_request: 30188
+author:
+type: changed
diff --git a/ee/spec/mailers/ci_minutes_usage_mailer_spec.rb b/ee/spec/mailers/ci_minutes_usage_mailer_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..80b6327f538542cb2f86570141091afc3c24a2c6
--- /dev/null
+++ b/ee/spec/mailers/ci_minutes_usage_mailer_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe CiMinutesUsageMailer do
+  include EmailSpec::Matchers
+
+  let(:namespace_name) { 'GROUP_NAME' }
+  let(:recipients) { %w(bob@example.com john@example.com) }
+
+  shared_examples 'mail format' do
+    it { is_expected.to have_subject subject_text }
+    it { is_expected.to bcc_to recipients }
+    it { is_expected.to have_body_text body_text }
+  end
+
+  describe '#notify' do
+    it_behaves_like 'mail format' do
+      let(:subject_text) do
+        "Action required: There are no remaining Pipeline minutes for #{namespace_name}"
+      end
+
+      let(:body_text) { "#{namespace_name} has run out of Shared Runner Pipeline minutes" }
+
+      subject { described_class.notify(namespace_name, recipients) }
+    end
+  end
+
+  describe '#notify_limit' do
+    it_behaves_like 'mail format' do
+      let(:percent) { 30 }
+      let(:subject_text) do
+        "Action required: Less than #{percent}% of Pipeline minutes remain for #{namespace_name}"
+      end
+
+      let(:body_text) { "#{namespace_name} has #{percent}% or less Shared Runner Pipeline minutes" }
+
+      subject { described_class.notify_limit(namespace_name, recipients, percent) }
+    end
+  end
+end
diff --git a/ee/spec/services/ci_minutes_usage_notify_service_spec.rb b/ee/spec/services/ci/minutes/email_notification_service_spec.rb
similarity index 99%
rename from ee/spec/services/ci_minutes_usage_notify_service_spec.rb
rename to ee/spec/services/ci/minutes/email_notification_service_spec.rb
index f2254ce6177c7d76784ecc52e3e1f472e586966c..b80ed815186552dff6d3bec8a84448e69f15d43e 100644
--- a/ee/spec/services/ci_minutes_usage_notify_service_spec.rb
+++ b/ee/spec/services/ci/minutes/email_notification_service_spec.rb
@@ -2,7 +2,7 @@
 
 require 'spec_helper'
 
-describe CiMinutesUsageNotifyService do
+describe Ci::Minutes::EmailNotificationService do
   shared_examples 'namespace with available CI minutes' do
     context 'when usage is below the quote' do
       it 'does not send the email' do
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0e227370741d100de7139e3525984c729e1d3843..270a8866e5fca025fc6c9e9a099435455d94accc 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -393,6 +393,12 @@ msgstr ""
 msgid "%{name} found %{resultsString}"
 msgstr ""
 
+msgid "%{name} has %{percent} or less Shared Runner Pipeline minutes remaining. Once it runs out, no new jobs or pipelines in its projects will run."
+msgstr ""
+
+msgid "%{name} has run out of Shared Runner Pipeline minutes so no new jobs or pipelines in its projects will run."
+msgstr ""
+
 msgid "%{name} is scheduled for %{action}"
 msgstr ""
 
@@ -23887,6 +23893,12 @@ msgstr ""
 msgid "We heard back from your U2F device. You have been authenticated."
 msgstr ""
 
+msgid "We recommend that you buy more Pipeline minutes to avoid any interruption of service."
+msgstr ""
+
+msgid "We recommend that you buy more Pipeline minutes to resume normal service."
+msgstr ""
+
 msgid "We sent you an email with reset password instructions"
 msgstr ""