Benchmarking a mailer

We'd like to see how long it takes for a Mailer object to leave our server after the deliver command is sent. How could we do this? We'd like to get an accurate value (e.g. in milliseconds).

We were using Sendmail to send e-mail from our app, but Sendmail had the problem that it took too long to send some e-mails. So we switched to Postfix, which is quite a bit faster and more accurate. However, we're still using :sendmail as our delivery_method. It works, but could SMTP be faster?

Also, is there any way to prioritize Mailer objects? We'd like some e- mails to go out immediatly and some can be added to the end of the queue.

Thanks.

jhaagmans wrote:

We'd like to see how long it takes for a Mailer object to leave our server after the deliver command is sent. How could we do this? We'd like to get an accurate value (e.g. in milliseconds).

Wrap the call to your deliver_xxx method in Benchmark.realtime. This will of course only measure the time it takes to generate the mail object and until it is handed off to the mail server.

Since mails can be temporarily rejected multiple times (e.g. greylisting, full mailboxes etc.) you'll have to analyze your mailserver logs if you want to look at those times as well.

We were using Sendmail to send e-mail from our app, but Sendmail had the problem that it took too long to send some e-mails. So we switched to Postfix, which is quite a bit faster and more accurate. However, we're still using :sendmail as our delivery_method. It works, but could SMTP be faster?

Conventional wisdom says that bulk mailings should be done via SMTP instead of local delivery, but I've had the opposite experience with Postfix; here delivery via :sendmail to a mailserver running on the same machine was a lot faster than using :smtp. Your mileage may vary according to server hardware, mail type, size and the amount of mails that are being sent at once.

Also, is there any way to prioritize Mailer objects? We'd like some e- mails to go out immediatly and some can be added to the end of the queue.

That is something you'll have to configure in your mail server. AFAIK Postfix doesn't have a prioritization built in. You might want to consider using different postfix instances to implement that kind of behaviour.

Regs, Sven

Hi Sven,

Thanks! Benchmarking the Mailer.deliver commands returns about 45 ms of elapsed time when sending through SMTP and 250 ms when sending through sendmail, so that at least reduces the time it takes to get the e-mail to Postfix. Now I'll just have to look at optimizing Postfix.

There's one specific domain we'd like to instantly mail to. Will it save DNS-lookup time if I'd add the mailserver at the other end to our hosts file? If so, should we use the MX-record (mail.domain.com) or just the domain part of the e-mail address (domain.com)?

Thanks again!

jhaagmans wrote:

Hi Sven,

[...]

There's one specific domain we'd like to instantly mail to. Will it save DNS-lookup time if I'd add the mailserver at the other end to our hosts file? If so, should we use the MX-record (mail.domain.com) or just the domain part of the e-mail address (domain.com)?

Right idea, but a fragile approach. If upstream ever changes the IP address of the mail server you'll still be trying to deliver to the old host, which may cause tons of bounced mail before you catch it.

I'd recommend installing a caching-only DNS server on your mail server. If you don't want to get into the overhead of installing and maintaining BIND you can try a something smaller that works just as well, like dnsmasq (be sure to turn off dnsmasq's DHCP capabilities though).

YMMV, depending on the amount of mail you're generating. For ten mails a day you won't see much of an improvement, but several thousand will at the very least help taking load off of your DNS server.

Regs, Sven

Thanks for suggesting BIND, I usually only install BIND on a server running a nameserver, but this helps :slight_smile:

I've decided to go another way though. We can use the SMTP server on the receiving end directly from Rails, because it accepts direct SMTP requests from our server. Now I'd like to use two ActionMailer configurations: one using our own SMTP server (Postfix) for regular outgoing e-mails with low priority. And one using the remote SMTP server. We'd like to decide which SMTP server it should go to based on the Mailer method used. E.g. one mailed method called "notifier" and one called "urgent_notifier".

How can I accomplish this?

Thank you!