2

I'm trying to find a faster way to send e-mail using MailJet. The function below is called within a loop so each loop iteration is an individual e-mail. In my test case it was taking 19 seconds to send 10 emails. Their support recommended turning ssl off and using port 80 instead of 465, this sped it up to 13-14 seconds, but this is still too slow. I tried SMTP sending using PEAR and PHPMailer, there was no difference between the two, same speed for both. Any ideas why this is so slow?

function sendViaMailJet($mailTo, $mailSubject, $mailBody, $mailFrom="noreply@mysite.com") {
    global $error;
    require_once('class.phpmailer.php');
    $toArray = explode(',', $mailTo);
    $mailBody = makeMailJetHtmlBody($mailBody);

    $mail = new PHPMailer();
    $mail->IsSMTP();
    $mail->SMTPDebug = 1;  // debugging: 1 = errors and messages, 2 = messages only
    $mail->SMTPAuth = true;  // authentication enabled
    //$mail->SMTPSecure = 'ssl';
    $mail->Host = 'in.mailjet.com';
    $mail->Port = 80;
    $mail->Username = 'XXXXXXXXX';
    $mail->Password = 'XXXXXXXXX';
    $mail->SetFrom($mailFrom, 'My Site');
    $mail->AddReplyTo($mailFrom, 'My Site');
    $mail->isHTML(true);
    $mail->Subject = $mailSubject;
    $mail->Body = $mailBody;
    foreach($toArray as $toAddress) $mail->AddAddress($toAddress, $toAddress);
    //$mail->AddBCC('me@mysite.com', 'Gordon');

    if(!$mail->Send()) {
        $error = 'Mail error: '.$mail->ErrorInfo;
        return false;
    }
    else {
        //$error = 'Message sent!';
        return true;
    }
}

UPDATE: I switched out PHPMailer and tried MailJets API, https://github.com/mailjet/mailjet-apiv3-php-simple. It was a little faster, a 10 e-mail test takes ~8 seconds now for http and https.

UPDATE I switched back to using PHPMailer and did a few adjustments from the recommendations below. It is still taking ~8 seconds to send 10 e-mails. Here is my test file...

<?php 
//@@@@@@@@@@@@@@@@@@@@@@
//START Init PHPMailer: This block of code only runs once per page
//@@@@@@@@@@@@@@@@@@@@@@
$mailx = new PHPMailer();
$mailx->IsSMTP();
//$mailx->SMTPDebug = 1;  // debugging: 1 = errors and messages, 2 = messages only
$mailx->SMTPAuth = true;
//$mailx->SMTPSecure = 'ssl';
$mailx->Host = 'in.mailjet.com';
$mailx->Port = 80;
$mailx->Username = 'xxxxxxxxxxxxx';
$mailx->Password = 'xxxxxxxxxxxxx';
$mailx->isHTML(true);
$mailx->SMTPKeepAlive = true;
//@@@@@@@@@@@@@@@@@@@@@@
//END Init PHPMailer: This block of code only runs once per page
//@@@@@@@@@@@@@@@@@@@@@@

function doMailJet($mailx, $mailTo, $mailSubject, $mailBody, $monitor=true, $mailFrom="noreply@mysite.com")
{
    $toArray = explode(',', $mailTo);

    $mailx->AltBody  = $mailBody; //This is the body in plain text for non-HTML mail clients
    $mailBody        = makeMailJetHtmlBody($mailBody);
    $mailx->Subject  = $mailSubject;
    $mailx->Body     = $mailBody;
    $mailx->From     = $mailFrom;
    $mailx->FromName = 'Message from MySite';
    $mailx->addReplyTo($mailFrom, 'Reply to MySite');
    foreach($toArray as $toAddress) $mailx->addAddress($toAddress);
    //if($monitor) $mail->AddBCC('gordon@mysite.com', 'Gordon');

    if(!$mailx->send()) {
        //echo 'Message could not be sent.';
        echo 'Mailer Error: ' . $mailx->ErrorInfo;
        return false;
    } else {
        //echo 'Message has been sent';
        return true;
    }
}

echo 'Testing doMailJet...<br>';
$time_start = microtime(true); //Lets see how long this is going to take.
for ($x=0; $x<=10; $x++) {
  echo "Sending: $x <br>";
  doMailJet($mailx, 'gordon1977@mySite.com','Testing 123','Test Message',false);
}
echo 'getTimeElapsed: '.getTimeElapsed($time_start);
?>
gfrobenius
  • 3,987
  • 8
  • 34
  • 66
  • is $mailTo an array of all the addresses your sending to ? –  Aug 31 '14 at 21:28
  • It is, but it is not being used in that fashion right now. Right now $mailTo will only ever contain one e-mail address at a time. One e-mail per loop. Their support just pointed me to this: https://github.com/mailjet/mailjet-apiv3-php-simple I'm going to try it next. – gfrobenius Aug 31 '14 at 21:32
  • that's the problem, your initialising a whole class for every single email. its clearly built for taking an array of emails, so why not do that. –  Aug 31 '14 at 21:34
  • Because each e-mail subject and body is different. I'm about to add some updates to the original question. – gfrobenius Aug 31 '14 at 22:10
  • you still dont want to loop all the 'setup' move subject and body into the loop –  Aug 31 '14 at 22:11
  • that's still slow, i push 30-40 html rich emails through a second. but not to a remote site (which could be some or all the overhead –  Aug 31 '14 at 22:17
  • I moved all the 'setup' out of the function like you recommended (everything above $mail->SetFrom()). Then I added another argument to pas in the PHPMailer object. It increased the speed to 7 seconds. Agreed, it should be much faster like you said. I think it might have to do with checks MailJet might be doing as stated here: http://stackoverflow.com/a/8143978/3112803 – gfrobenius Aug 31 '14 at 22:27
  • your sending each message over http to another location, that's going to be a lot slower than having a mail server installed on the same machine(network) –  Aug 31 '14 at 22:29
  • You should also set `$mail->SMTPKeepAlive = true;`. This will reduce your SMTP overhead enormously. – Synchro Sep 01 '14 at 06:58
  • Also make sure you are using the latest PHPMailer - I made SMTP much faster in 5.2.7. – Synchro Sep 01 '14 at 07:00
  • Thanks, I was at version 5.1. I upgraded and added `$mail->SMTPKeepAlive = true;` unfortunately a 10 e-mail test still takes ~8 seconds. It must be on MailJets end. – gfrobenius Sep 01 '14 at 17:25

0 Answers0