Introduction

Email providers enforce sending rate limits to prevent abuse and protect their reputation. When an account exceeds the allowed number of messages per hour or per day, the provider temporarily blocks further sending. This affects both transactional and marketing emails, causing delivery delays and potential business impact.

Symptoms

  • Outgoing emails are queued but not delivered
  • SMTP server returns 452 4.7.0 Too many messages sent or 421 Rate limit exceeded
  • Email sending works again after a cooldown period (usually 1 hour)
  • Mail queue builds up with deferred messages
  • Error message: 452 4.5.3 Too many recipients or 421 4.7.0 Try again later

Common Causes

  • Bulk email campaign exceeding the provider's hourly sending limit
  • Application sending individual emails instead of using batch API
  • Compromised account sending spam, triggering rate limits
  • Shared hosting account with other users consuming the rate limit pool
  • Misconfigured mailing list sending all messages at once instead of throttling

Step-by-Step Fix

  1. 1.Check the current rate limit status: Verify the limit and usage.
  2. 2.```bash
  3. 3.# Check mail queue for deferred messages
  4. 4.mailq
  5. 5.# Check provider rate limit documentation
  6. 6.# Gmail: 500 messages/day (consumer), 2000/day (Workspace)
  7. 7.# Outlook: 300 messages/day (consumer)
  8. 8.`
  9. 9.Implement sending throttling: Space out messages over time.
  10. 10.```python
  11. 11.import time
  12. 12.import smtplib

# Throttle sending to 50 messages per hour for i, recipient in enumerate(recipients): send_email(recipient) if (i + 1) % 50 == 0: print(f"Sent {i+1} messages, waiting 1 hour...") time.sleep(3600) ```

  1. 1.Use a transactional email service for high-volume sending: Bypass provider limits.
  2. 2.```python
  3. 3.# Use SendGrid, Amazon SES, or Mailgun instead of SMTP
  4. 4.import sendgrid
  5. 5.sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
  6. 6.message = Mail(from_email='sender@example.com', to_emails='recipient@example.com')
  7. 7.sg.send(message)
  8. 8.`
  9. 9.Clean up the mail queue after the rate limit resets: Send deferred messages.
  10. 10.```bash
  11. 11.# For Postfix, flush the queue after rate limit resets
  12. 12.postqueue -f
  13. 13.# Check queue status
  14. 14.mailq
  15. 15.`
  16. 16.Monitor sending rates to prevent future limit violations: Set up alerting.
  17. 17.```bash
  18. 18.# Monitor Postfix sending rate
  19. 19.tail -f /var/log/mail.log | grep "sent" | wc -l
  20. 20.# Alert when approaching the hourly limit
  21. 21.`

Prevention

  • Use transactional email services (SendGrid, SES, Mailgun) for high-volume sending
  • Implement sending rate limiting in application code before reaching provider limits
  • Separate transactional and marketing email streams to avoid competing for rate limits
  • Monitor sending rates and alert when approaching provider thresholds
  • Configure mailing list software with built-in throttling and rate limiting
  • Secure email accounts with strong authentication to prevent compromise and abuse