diff --git a/app/models/mailer.rb b/app/models/mailer.rb
index 53c01e1cd..f4c31cf12 100644
--- a/app/models/mailer.rb
+++ b/app/models/mailer.rb
@@ -31,9 +31,15 @@ class Mailer < ActionMailer::Base
   class DeliveryJob < ActionMailer::MailDeliveryJob
     include Redmine::JobWrapper
 
+    before_enqueue {throw :abort unless Mailer.perform_deliveries?}
+
     around_enqueue :keep_current_user
   end
 
+  class CurrentDeliveries < ActiveSupport::CurrentAttributes
+    attribute :disabled
+  end
+
   self.delivery_job = DeliveryJob
 
   # Overrides ActionMailer::Base#process in order to set the recipient as the current user
@@ -641,13 +647,14 @@ class Mailer < ActionMailer::Base
     end
   end
 
-  # Activates/desactivates email deliveries during +block+
+  # Activates/desactivates email deliveries during +block+, in the current
+  # thread only
   def self.with_deliveries(enabled = true, &)
-    was_enabled = ActionMailer::Base.perform_deliveries
-    ActionMailer::Base.perform_deliveries = !!enabled
-    yield
-  ensure
-    ActionMailer::Base.perform_deliveries = was_enabled
+    CurrentDeliveries.set(disabled: !enabled, &)
+  end
+
+  def self.perform_deliveries?
+    ActionMailer::Base.perform_deliveries && !CurrentDeliveries.disabled
   end
 
   # Execute the given block with inline sending of emails if the default Async
@@ -736,6 +743,7 @@ class Mailer < ActionMailer::Base
   end
 
   def self.deliver_mail(mail)
+    return false unless perform_deliveries?
     return false if mail.to.blank? && mail.cc.blank? && mail.bcc.blank?
 
     begin
diff --git a/test/unit/mailer_test.rb b/test/unit/mailer_test.rb
index ab880ef45..660eba5ac 100644
--- a/test/unit/mailer_test.rb
+++ b/test/unit/mailer_test.rb
@@ -1103,6 +1103,25 @@ class MailerTest < ActiveSupport::TestCase
     assert ActionMailer::Base.perform_deliveries
   end
 
+  def test_with_deliveries_off_should_not_enqueue_delivery_jobs
+    previous_adapter = ActionMailer::MailDeliveryJob.queue_adapter
+    ActionMailer::MailDeliveryJob.queue_adapter = :test
+    Mailer.with_deliveries false do
+      Mailer.test_email(User.find(1)).deliver_later
+    end
+    assert_empty ActionMailer::MailDeliveryJob.queue_adapter.enqueued_jobs
+    assert ActionMailer::Base.deliveries.empty?
+  ensure
+    ActionMailer::MailDeliveryJob.queue_adapter = previous_adapter
+  end
+
+  def test_with_deliveries_off_should_not_disable_deliveries_in_other_threads
+    Mailer.with_deliveries false do
+      Thread.new { Mailer.test_email(User.find(1)).deliver_now }.join
+    end
+    assert_equal 1, ActionMailer::Base.deliveries.size
+  end
+
   def test_token_for_should_strip_trailing_gt_from_address_with_full_name
     with_settings :mail_from => "Redmine Mailer<no-reply@redmine.org>" do
       assert_match /\Aredmine.issue-\d+\.\d+\.3@redmine.org\z/,
