1

I am using two email templates and tested performance:

  1. 100 emails with 25 products per email took 24 seconds.
  2. 100 emails with 12 products per email took 16 seconds.

All images (e.g. logos, banners, products) are text that invoke URLs where images are hosted on the server).

I feel that the increase in time (from 16 to 24 seconds just for 100 emails) is dramatic, considering that I am only adding a few KB per product. If this is happening only sending 100 emails, the impact sending thousands of emails in terms or time and performance to complete the sends would be high. My code uses this:

....
require_once "/.../ea-php70/root/usr/share/pear/Mail.php";
$params['sendmail_path'] = '/usr/lib/sendmail';
$mail_object =& Mail::factory('sendmail', $params);
$timeoutSet = set_time_limit(18000); // set script time out to 5 hours 
...
for ($i = 1; $i <= 100; $i++) {
    ...
    $_mail = $mail_object->send($recipients, $headers, $sendContent); 
    ....
}
....

How can I make my PEAR::Mail implementation faster for sending bulk emails? I am suspecting that maybe my server is throttling emails or that I need to change some PEAR::Mail settings, or maybe use SMTP instead of Sendmail. Any ideas? Thank you.

UPDATE 1:

I have an 8 core, 16 thread processor. One thing I have done is to run my script in parallel from different tabs of the web browser so that for example instead of taking 4 minutes for sending 8000 emails, it only takes 1 minute because I send them in 4 batches of 2000 emails each, running the script simultaneously in 4 parallel and independent processes. I am trying to find other ways to expedite even more this CPU intensive task and I am wondering if PEAR::Mail has some settings that I can modify to send emails faster.

Jaime Montoya
  • 6,915
  • 14
  • 67
  • 103
  • 2
    I'm not convinced the bottleneck is in the actual send, but in how you are composing the messages, but all relevant code for content generation is missing. You should do more profiling to be sure. And you could consider sending in batches, using [PEAR::Mail_Queue](https://pear.php.net/package/Mail_Queue) or similar – msg Apr 13 '20 at 16:03
  • @msg I updated the code in my question showing how I am using `for ($i = 1; $i <= 100; $i++)` and within that loop I use the `send()` method of `PEAR::Mail`. Within that loop what I am doing is to customize the content that I am sending to each subscriber, specifying `$headers['To']`, and basic things like that. Do you think composing the message is really taking so long? Are you suggesting that if within the loop I remove `$_mail = $mail_object->send($recipients, $headers, $sendContent); ` it would still be slow because what is consuming the time is my content generation and not `PEAR::Mail`? – Jaime Montoya Apr 13 '20 at 16:19
  • 1
    Yes, if you are interacting with the database for the mail customization, retrieving products, etc. I'd bet my money that's where your bottleneck is. You'd have to profile each section of the code to be sure. – msg Apr 13 '20 at 16:23
  • @msg I tested and the problem definitely is not the way I am composing the messages. If I do not invoke `$_mail = $mail_object->send($recipients, $headers, $sendContent);` in my code, it only takes a fraction of a second to execute thousands of iterations retrieving stuff from my database. The problem is invoking `$_mail = $mail_object->send($recipients, $headers, $sendContent);` to send the content for each of those thousands of iterations. Then it becomes slow. – Jaime Montoya Apr 15 '20 at 16:21

1 Answers1

0

The time increases considerably when you send the same number of e-mails but increase the number of products that are shown in each e-mail. This indicates that not the sending of the e-mails is the problem, but the creation of the mail content.

If all mails contain the same products, then generate the content only once, and re-use that for each e-mail.

If you have personalized e-mails, generate the non-personalized mail content only once and re-use that.

cweiske
  • 30,033
  • 14
  • 133
  • 194