Speeding up email delivery on Rails
There’s one thing that has always bugged me: when using Sendmail to deliver email from Action Mailer in Ruby on Rails, it always takes a few seconds for the email to be sent, thus slowing down whatever task the user is trying to accomplish.
When, for example, a user signs up for your service, you might want to send her a welcome email, but what if this slows down the sign up procedure a bit? Sure, a couple of seconds are not that much, but your new user might think the site is slow, which is not desirable.
In the past, we fixed this behaviour by adding the email to a queue in the DB which was then processed by a cron script every few minutes.
Sure, it worked, but what about using Sendmail’s own queue to achieve the same result? What if Rails could simply pass the email to Sendmail and then get back to work?
Here’s an easy way to achieve this.
Add the following to your config/environments/production.rb:
config.action_mailer.sendmail_settings =
{:arguments => "-i -t -O DeliveryMode='b'"}
Pros&cons: using the DB queue will allow for easier error handling, but then emails will be delayed by a few minutes depending on you cron settings. Using Sendmail’s queue allows for instant email delivery, but makes error handling a tad harder.
I think going the Sendmail route is the right decision for most projects. You choose. :)
This post was written by Michele 10 months, 2 weeks ago on October 14th, 2007 late at night.
Tags: .















Federico Feroldi 10 months, 1 week ago
Actually I prefer the queue approach because it doesn’t require a fork and is more scalable (you can have multiple delivery agents).
To lower the delay you can make use of a message queue (like activemq, spread and many others) to notify the agents that a new message was added to the queue.
Or, to make the things easy, you can make the agent listen to HTTP notifies coming from the sending process, so you can queue the message on the database and then notify the agent with an HTTP request.
Michele 10 months, 1 week ago
Actually, we aren’t forking: we’re using asynchronous sending, thus the email is added to Sendmail’s own queue without having to wait for it to be delivered.
The biggest problem I see is with error handling and maybe with scalability once you start sending thousands of email a minute, in which case you’d better set up a proper mail server, anyway. ;)
Post a comment