I found few older threads that have a similar issue but most of them didn\'t have answers or if they had, the suggestions weren\'t relevant in my case.
I had a compl
Sending e-mails is generally a slow activity. For whatever reason (network traffic, traffic priority, mailer daemon implementation, etc) it takes a lot of time. One way to handle e-mail traffic is to not send it in line with the response you're generating. A better solution is to do it asynchronously. One suggestion above (to use a work queue and empty the work queue using a cron job) is great. The only caveat (depending on the volume of traffic) is that the time to send all the e-mails in the work queue may be greater than the time interval between cron tasks.
Another option (and this is my preferred option) is to use a messaging layer like Rabbit MQ (probably more good books/posts on the topic) or Zero MQ (if you're a more solid programmer). In this case you create an event "send-email" and push it to a queue. There are multiple queue listeners. Once your PHP script pushes the e-mail to send to a queue, it's done and moves on. One of the queue listeners picks up the message and sends the e-mail.
This can allow you great flexibility in building a solution. Since most of the time to send e-mails appears to be wait time, you could run 10 consumer programs to send e-mail, knowing that most of the time the individual senders will be idle. (It's been my experience in sending e-mail is long wait time but not high CPU load). By running a fixed number of consumers (your PHP script is the producer), you can throttle the rate at which you send mail/devote system resources to sending mail.
I have implemented variants of this approach and the up side is that other things that need to happen that are slow (like resizing images) can be handled using the same pattern. As you grow you can off-load portions of the work to other machines simply by starting up consumers on those machines.
From server where you have the PHPMailer hosted, try:
telnet smtp.gmail.com 465
You'll see how long it took to establish connection between your server and smtp.gmail.com
If the delay between sending the emails is really a critical issue, have you considered implementing a form of multithreading? The delay per message may be the same, but it would essentially be cut in half if you send two enails at a time.
An easy way to do this would be to implement a queue, and the message is sent via a non-blocking HTTP/SQL call. In this way you could send as many as you like with a minimal delay.
I also suggest, if possible, find the gmail server with the lowest latency and add it to your hosts file to elimiinate DNS lookups.
Also some performance hints: You only need to require_once() for the include file, but you're requiring it on every call (as an aside, include_once() is faster). Why not create a $mail object only once and reuse it whenever you need to call sendemail()?
Also why not pass message1, subject1, etc. as one array and message2, subject2, etc. as a second array? Passing fewing parameters during procedure calls in general (at least in classical programming) tends to speed things up.
As an aside -- no idea if this is possible -- Perhaps there is a way to maintain a constant connection to smtp.gmail.com. This would eliminate a lot of overhead as well.
Also, is relaying your messages through your own meial server an option? It'd elimiinate the delay.
Finally, I came across this response from Google: [Gmail Sending Limits `
Thank you for your message.
I understand you have a query regarding the Google Apps for Business sending limits. As
mentioned in our Help Center article at http://support.google.com/a/bin/answer.py?hl=en&
answer=166852, the daily limitation is 2000 messages in a 24-hour period not day. In general, our
servers can tolerate one message per second until sending limits are hit. We really don't
have an hourly or minute limitation for sending. If you send messages too quickly you may
get rate-limited but the account should not lock out.
By rate-limt, since in general one message per second, if you try to send too many messages per second
you may get a message telling you that the message cannot be send or you must wait before sending a
message.
`
I'd be happy to write a class that conforms to these limits if you need one. Please let me know, shouldn't take too long.
Recommendation: Use another email host/relay
The slowness (or failure due to timeouts) is because Google supports IPv6 addressing but your network does not. (e.g. Digital Ocean does not yet support IPv6 for SMTP traffic). So, use this:
$mail->Host = gethostbyname("smtp.gmail.com");
gethostbyname() will return the IPv4 address.
For me, my PHPMailer script went from ~2 minutes execution time to <4 seconds
From your description I'd guess it looks like DNS caching issue perhaps. You may want to investigate in more details time being spent to resolve DNS record
From application point of view, it might be advisable for you to send emails asynchronously rather than synchronously, meaning via background e.g. CRON job. This is solution suitable if you send say more than 10 emails per hour. Ensures full control over email stack queue, tracking errors, no latency or page crashes for frontend users.
One of solutions to remove waiting from client to server is to move sending emails to crontab. So when client clicks for sending, php adds email and message to queue, and then every minute you send queued messages by cron.
In addition you can add debug info into your script by having $start = microtime(true);
at the top of the script and echoing echo "Line ".__LINE__.":"round(microtime(true) - $start, 3)."sec<br>";
at every line.