Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

For the past two years I have been sending out our monthly newsletter to our customers using the following code -- I've wanted to post here for a while and ask: Is there a way to send out an email to a few thousand people (4000) in ONE step? It is very important that BCC is used (for obvious reasons). Also, when I use the code below, it takes over an hour for the emails to get sent. During this period when someone visits our site, a visitor will occasionally get an internal server error which I'm think is related somehow to the mail/sendmail program.

Basically, I just want to know a quicker way to send out an email to a lot of people using BCC that sendmail can handle and that won't create errors. Just a note, this is not a spam email - these are emails we've accumulated over the past four years.

Thanks in advance!

---------------------------------------------------------
#!/usr/local/bin/perl require "Lite.pm"; $address = "hgy.emllst"; # file with email addresses $email_template = "email-sept-20-06.html"; # the 'email' in html form +at (looks pretty) $subject = "News for September 2006"; open(E,$email_template); @F = <E>; close(E); $filehtml = join("",@F); ## open up the file with the email addresses open(A,$address) || die "could not open $address for reading\n"; ## read in the email addresses into the address array @addresses = <A>; ## for each address in the list for ($i=0; $i < @addresses; $i++) { if ($addresses[$i] ne "") { ## send the customer an email my $msg = MIME::Lite->new( From =>'news@xxxxxxxx.com', To =>"$addresses[$i]", Subject =>"$subject", Type =>'text/html', Data =>"$filehtml"); $msg->send(); } }

20060927 Janitored by Corion: Changed PRE to code tags, as per Writeup Formatting Tips

Replies are listed 'Best First'.
Re: Sending out a mass email to our customers
by davorg (Chancellor) on Sep 27, 2006 at 11:04 UTC

    You can set a Bcc header by using the 'Bcc' key in the call to MIME::Lite->new. And you can give it multiple addresses by passing a reference to an array of addresses. You might not be able to send 4,000 messages in one go, but you'll certainly be able to send them at a better rate than your current one at a time.

    During this period when someone visits our site, a visitor will occasionally get an internal server error which I'm think is related somehow to the mail/sendmail program

    Maybe you should consider using a mail server that isn't also your web server.

    Your require "Lite.pm" is rather non-standard. You should really replace that with use MIME::Lite. There are a few other unusual pieces of code in there, like the way you unnecessarily read the whole address file into memory. The whole program would benefit from being reviewed by a more expert Perl programmer.

    And finally, more and more people are treating pure-HTML email as spam. For example, I never get to see any mail message that doesn't have a plain text version attached. If your message isn't spam then you might consider making it look less like spam.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Sending out a mass email to our customers
by zentara (Cardinal) on Sep 27, 2006 at 12:22 UTC
Re: Sending out a mass email to our customers
by derby (Abbot) on Sep 27, 2006 at 12:30 UTC

    If the data is the same for each person and you can sort the addresses by domain, then Mail::Bulkmail's use_envelope feature is probably your best bet (especially if the number of unique domains is small).

    -derby
Re: Sending out a mass email to our customers
by imp (Priest) on Sep 27, 2006 at 11:22 UTC
    A large portion of the delay when sending mail is the time spent communicating with the server. If you are sending identical content to these recipients then you could preprocess the address list and batch them by domain, with a max of 5ish people in a batch - to avoid cases where a large delivery list is treated as spam by the receiving server.

    You could also look at reusing the MIME::Lite object you created, changing the recipient and sending again. I haven't check the documents to see if this is supported, but it is worth researching to reduce time spent constructing the object.

Re: Sending out a mass email to our customers
by jdtoronto (Prior) on Sep 27, 2006 at 15:10 UTC
    Firstly, the last thing I would do is to use the Bcc field at all. It serves your purpose as far as hiding the destination addresses, but it does nothing to improve efficiency or speed. In fact if you use the Bcc the whole thing is treated as one email. You could use Mail::BulkMail but that would require a complete re-write and a new interface to learn. I would suggest the following - still using MIME::Lite
    • Emails should all be 'multipart/mixed' messages. Many servers now 'junk' any email that has nothing but HTML in it.
    • Each email should have a 'TEXT' type portion, which can usably point the reader to a link where the email can be read if they have difficulty.
    • Because you don't appear to customise the message, y9ou could use the 'pre-prepared part hack' as demerphg calls it in the documentation, you only prepare the MIME part once then you can attach it to as many messages as you like.
    • Clustering will help. But with only 4000 addresses, it may not help much.
    • Batching emails into groups of 4 or 5, maybe 10 at a time is good, then put in a gap (I usually use 3 seconds) so that you don't flood servers and if you have to work on your web server this will give you a small break to reduce server load.)

    jdtoronto