[Mimedefang] rate-limiting for outbound mails per sender

David F. Skoll dfs at roaringpenguin.com
Mon Feb 10 09:09:31 EST 2014

On Mon, 10 Feb 2014 07:08:38 +0100 (CET)
Steffen Kaiser <skmimedefang at smail.inf.fh-bonn-rhein-sieg.de> wrote:

> > what would be a good way to implement rate-limiting for outbound
> > mails per sender e.g. 50 recipients per smtp_auth sender per hour?

> I do this in filter_begin. There I detect the sender, assign a
> "SenderID" based on different rules and query a SQL database about
> the sum of recipients of this SenderID in the last hour & day. If the
> SMTP quota is not exceeded, the tuple (scalar(@Recipients), SenderID,
> NOW()) as added to the database.

Our CanIt product also implements rate-limiting, but we do it slightly
differently.  We keep a table like this (PostgreSQLisms, sorry...)

CREATE TABLE sender_rate_limit (
       sender     TEXT PRIMARY KEY,
       first_seen TIMESTAMP WITH TIME ZONE,
       count      INTEGER

Then when we see a RCPT from a sender (which can actually be an
envelope sender, the SMTP AUTH user, or the sending relay IP address)
we do the equivalent of:

# Update existing bucket
UPDATE sender_rate_limit SET count = count + 1 WHERE sender = '$sender' AND first_seen >= now() - '1 hour'::interval;
# If the previous update did not update any rows, then:
   # The next delete deletes a potential row where first_seen is
   # more than one hour old
   DELETE FROM sender_rate_limit WHERE sender = '$sender';

   # And start a new bucket.
   INSERT INTO sender_rate_limit(sender, first_seen, count) VALUES('$sender', now(), 1);

When it comes time to impose a rate limit, we can just do a:

SELECT count FROM sender_rate_limit WHERE sender = '$sender';

The lookups are very fast and don't require a SUM operation.  The
downside is that it doesn't keep a running hourly sum, but resets
(more-or-less) once an hour so a sender can actually exceed the rate
limit for a while if the timing window is just right.  In practice,
this has not been a problem.



More information about the MIMEDefang mailing list