SMTP rate limiting is how you keep your outgoing mail servers from getting hammered into oblivion and landing on every spam blacklist known to humankind.

Let’s see it in action. Imagine you’re sending out a newsletter to 100,000 subscribers. Without rate limiting, your mail server would try to blast all those emails out as fast as it possibly could. That looks really suspicious to receiving mail servers. They’re like, "Whoa there, buddy! That’s a lot of mail, really fast. You must be a spammer!" And bam, your IP addresses start showing up on blocklists.

Here’s a common setup using Postfix, a popular mail transfer agent (MTA). We’ll define limits for how many recipients a connection can send to, and how many recipients a single sender can send to per unit of time.

First, you edit your Postfix main configuration file, usually /etc/postfix/main.cf.

# main.cf
#
# Maximum recipients per connection
smtpd_recipient_limit = 500

# Maximum recipients per sender per hour
smtpd_sender_rate_limit = 10000
smtpd_sender_duration_limit = 1h

# Maximum recipients per sender per day
# smtpd_sender_rate_limit = 250000
# smtpd_sender_duration_limit = 24h

After saving main.cf, you need to reload Postfix for the changes to take effect.

sudo postfix reload

Now, let’s break down what’s happening with smtpd_recipient_limit. This setting caps the number of recipients a single SMTP session can deliver mail to. So, if you’re sending a message to user1@example.com, user2@example.com, and user3@example.com, that’s three recipients. If your smtpd_recipient_limit is 500, Postfix will stop accepting recipients for that specific connection after the 500th one. It’ll then expect a new SMTP connection to be established before it can accept more recipients for that sender. This prevents a single, very long RCPT TO: command list from overwhelming Postfix or causing issues downstream.

smtpd_sender_rate_limit and smtpd_sender_duration_limit work together to control how many messages a specific sender can send within a given time frame. smtpd_sender_rate_limit = 10000 means that a sender can send a maximum of 10,000 messages. smtpd_sender_duration_limit = 1h specifies that this limit applies over a one-hour period. So, if you have a sender newsletter@yourdomain.com and a smtpd_sender_rate_limit of 10,000 per hour, Postfix will start delaying or rejecting mail from newsletter@yourdomain.com once it hits that 10,000-message mark within any given hour. This is crucial for preventing sudden bursts of mail that look like spam. The system doesn’t just block the mail outright after the limit; it typically introduces delays, making your mail flow appear more human-like and less like an automated attack.

The real power comes when you combine these with other Postfix features. For instance, you can use anvil (the Postfix connection rate limiter) to limit the rate at which new SMTP connections are established from a single IP address. This is a good first line of defense.

# main.cf
anvil_rate_limit = 30/1m  # Max 30 new connections per minute from one IP

This prevents a single IP from opening hundreds of connections simultaneously, which is another common spam indicator.

The smtpd_client_restrictions directive is where you can tie these together and add more granular controls. You can specify actions based on sender, recipient, or client IP.

# main.cf
smtpd_client_restrictions =
    permit_sasl_authenticated,
    permit_mynetworks,
    hash:/etc/postfix/client_access,
    check_client_access hash:/etc/postfix/rate_limit_map,
    reject_unauth_destination

Here, check_client_access hash:/etc/postfix/rate_limit_map would allow you to define specific IPs or networks that should be subject to tighter rate limits, or even completely blocked if they misbehave too much.

The one thing most people don’t realize is that Postfix’s rate limiting, especially smtpd_sender_rate_limit, is not a hard cutoff that immediately starts rejecting mail. Instead, it often introduces delays for messages that exceed the limit. This is a sophisticated mechanism designed to make your outbound mail appear more "natural" and less like a bot sending massive volumes. The system will queue these delayed messages and send them out later, smoothing out the delivery curve. You can observe these delays in your mail logs, where messages might appear with a significant time gap between the initial submission and the actual delivery attempt.

The next step is often dealing with the implications of these delays on your recipient engagement metrics and understanding how to tune these limits dynamically based on real-time mail flow analysis.

Want structured learning?

Take the full Smtp course →