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