I made a quick PHP script on my server containing a call to mail() and started testing it. The html page always loads instantly, so I assume that means the PHP containing the call to mail() is finished executing. However, the emails sent from mail() are only ever being received every 10-20 minutes after the call. Why the delay? Does mail() trigger external programs? (the emails are being sent to a gmail email account if that's relevant)
The behavior you are seeing has nothing to do with PHP's mail() function. Instead, it is the SMTP mail server which PHP hands off the message to, which is taking time to deliver. That service is known as a mail transport agent, or MTA.
There are lots of potential reasons it won't be delivered immediately. Possibly, the delay you see is greylisting on the receiving server, meaning that the receiving mail server refuses to accept the message until the sending server (which your PHP script handed it to) tries a few times to resend it. Well-behaved MTA's will retry failed send attempts, but spam servers often don't, making this a simple but effective method for cutting down spam.
It could even be as simple as a long queue of messages on the SMTP server waiting to be sent, whereby yours are waiting in line. (Really greylisting is more probable though)
Most important to remember though is that email is not intended to be instantaneous and therefore never guaranteed to be instantaneous. In the past decade or so we've gotten accustomed by and large to email being delivered really quickly, but you can never promise quick delivery.
Just as #Michael Berkowski said, it's not the mail() function itself. mail() works by calling your systems built in SMTP courier software. It then automatically negotiates the conversation with the receiving system by performing the necessary DNS lookups to find the proper mail server. Then that server picks up your message, checks your system through grey-listing and reverse DNS lookups, scans it and runs it against it's own spam/virus protection, then finally delivers. Also many mail servers delay unknown sending servers to prevent against mail DOS'ing and fishers.
Today I was setting up my local devserver and had same problem. Sending mail fom php via mail()-function was very slow. As already mentioned, the problem was the sendmail-setup (/var/log/mail.log):
My unqualified host name (devserver) unknown; sleeping for retry
I had to make my hostname resolvable folling this guide:
https://linuxconfig.org/sendmail-unqualified-hostname-unknown-sleeping-for-retry-unqualified-hostname
tldr;
edit /etc/hosts
127.0.0.1 localhost.localdomain localhost devserver
127.0.1.1 devserver
Maybe it will help somebody, too
Related
I am sending a lot of emails per hour using PHPMailer on our intranet.
Most of the emails the application is sending are being bouced back with:
Domain *** has exceeded the max defers and failures per hour (5/5 (100%)) allowed. Message discarded.
I have seen that there are fixes for this using CPanel but I don't have CPanel installed on this server.
Does anyone know of another way around it?
PHPMailer has no features to mitigate this, so it's up to either the calling code or underlying infrastructure to do it. There are several strategies you could follow:
Generate your message requests into a queue, then have a separate
process that sends them at a rate that will pass your upstream mail
server's restrictions. I suspect this is what cpanel will be doing.
Get the upstream mail server limits lifted - if this is an intranet,
there is no real reason to limit these sends.
It may be that it's not your sending but your upstream mail server
that is having the problem. In that case the mail server needs tuning
to do at least per-domain throttling. Postfix has support for this
out of the box, but you will need to configure it.
I am send email using php mail function.But it takes long time to receive to the user.It should receive with 10 minutes.how can i do that and why it is taking long time to receive more than 30 minutes its taking now.
it might be that the recipient is not the one to blame, sometimes it is due to the ISP. In our country, our ISP provider accepts lots of requests that the queue may pile up. This is when using the ISP provided SMTP server as a SMTP relay server.
Also the PHP mail() function has a limit depending on you host or server (first a volume limit and then a limit preventing you to send X emails in a row).
Were I you, I would use third parties APIs, like SendGrid or MailChimp... (they also provide mail tracking, error reports, opting out...) and are quite easy to use.
I have over 4,000 users who subscribed to weekly updates via email. To send an email, I simply use:
mail($to,$subject,$message,$headers);
Which works perfectly fine. My question is: how many emails can you send at once? Can I send all 4,000 at once by stepping through array of emails inside a loop? Or will that cause a time-out situation, wjere only part of the list receives emails?
Generally, your limit is PHP's memory allocation and script timeout, both of which can be increased. A bigger limiting factor is spam firewalls, which typically limit the number of emails that can come from a server and to another domain. Bulk email services use intervals to limit the amount of mail sent to any given domain during a given time period.
PHP has no limit, and you can do what you say and run it in a tight loop.
On linux it is sendmail, or a sendmail clone. If it starts to get overloaded it should start queueing your mails, and delivering them when it can. For Windows you have a socket connection, and I suppose the mail server might start refusing connections if it got overloaded.
Unless you are in a hurry to send them all, consider a sleep(2) between each call to mail(). If all goes smoothly then try sleep(1) the next time. Then usleep(500000) next time, etc. (UPDATE: following Matt's suggestion, put set_time_limit(10) inside the loop to avoid running out of CPU time.)
If you want them sent out even quicker you round-robin with multiple local relays. (On windows you could handle this by setting the SMTP php.ini setting; on linux you'd use on of the libraries that sends email over a socket.) Or consider a professional mail broadcasting service, where they take care of all these issues for you.
EDIT Just saw your comment about running it from your Mac. I'd assumed a server situation, with a real mail server with a global IP. If your Mac is behind a firewall you are most likely set to forward all your email to your ISPs mail server. Your ISP may well get upset about receiving 4000 emails from you in a short period of time. (E.g. they may assume your machine has been compromised by a virus and shut you down.)
Also, on shared hosting, agreeing not to send out lots of email is often part of the contract. So be careful there too.
It does not depend on php, but it depends on your sendmail server capability and your hosting provider support on the limit of emails that you can send with in a span of time..! PHP only puts your email in the sendmail queue...!
Considering that loop will be sequential you can send them all at once by looping. It's more mailserver dependent, rather than PHP.
Although if you're using WAMP, that might cause a problem, because behavior of mail() under windows is different. Instead of talking to an MTA it tries to use sockets to deliver mail.
Giving exact numbers is not possible.Its depends on your mail server & maximum execution time.
Best practice to send large number of email is "cron job"
I'm improving PHP mailing list code that uses mail() in a loop while iterating through all subscribers. The script used to display a "Maximum execution time of 30 seconds exceeded" error which I solved by adding set_time_limit(0);.
Now there's no error but it took about seven minutes to send 100 messages. What are my options?
Will sending just a single message with all subscribers in BCC help or is it the same "behind the scenes"?
Sending to all as BCC will be a lot faster. The code will execute faster and mail() will be executed only once.
This is the quick fix, but as mentioned, a large BCC list is a safe road to the spam folder. However, using mail() is a sure destination to spam too.
If you want to actually improve it, use PHPMailer from SourceForge and send via SMTP (less spam hits) using cron in batches of X emails once.
The PHP docs state:
Note:
It is worth noting that the mail() function is not suitable for larger volumes of email in a loop. This function opens and closes an SMTP socket for each email, which is not very efficient.
For sending large amounts of email, see the » PEAR::Mail, and » PEAR::Mail_Queue packages.
Sending to all subscribers by specifying them in BCC shouold work faster. Though, while it might be a good option for some private environment, I would not suggest to do that in public web pages/systems, as many might consider such email being a spam.
One option would be to send emails via cron job. In that case, it doesn't really matter how much time it takes to send an email, as long as all emails are eventually sent.
Since you're simply asking for options, here are a few:
Profile your code, and see why its slow. Maybe you could iron out a few efficiency issues.
Relying on the mail() function is usually not advisable, especially since better alternatives like swiftmail or Zend_mail exist. Although these might be overkill for small mailing requirements
It could, possibly, be a server related issue? Maybe talk to your server administrator.
Cron Job is better idea. I used this and it works...
Profile you code will help you to figure out the problem.
I do recommend sending the mail via BCC because it will be a lot faster. Your script just has to make one connection to the SMTP server and this server will do the rest for you.
I would also take a look at for example PHPMailer or PEAR::Mail.
The bad thing about the mail() method for bulk mails is that it will open a new socket to a SMTP server for every email thats send.
A good mail library will create a socket connection to the SMTP server once and will then send all the emails and closes it at the end.
To speed it up a bit more you could also look at your SMTP server configuration (if possible) and try to increase the daemons etc.
You might also want to take in consideration that some SMTP servers have maximums you can send.
I'm developing a site that sends email notifications to users after certain events/user actions (tagged in a photo, added as a friend, etc.)
From my experience, sending emails from a web server can be slow. For instance when creating a new user I will send an email to confirm/welcome the account. However, there is short pause sometimes waiting for the page to load while it finishes sending the email.
My fear is that, if I ever have a problem connecting to a mail server or the mail server is overloaded, it will bottleneck my application/page loads
So my question is, what is the best way to send emails from a web application that sends emails on consistent basis?
Should I create a queue system, by storing email content in a database and then run scheduled cron jobs to process all the undelivered emails?
Or should I just send the email directly after a user completes an action/event (creating a member account, tagged in a photo, etc...)?
No. Ask your sysadmin to configure mail server. Correctly configured mail server should be faster then storing messages on database.
Use local sending to avoid network delays.
[mail function]
sendmail_path = /usr/sbin/sendmail
in php.ini
It would work even if mail server is down (message will be queued).
Set up a mail relay on the local machine. That way you do not have to bother with cron and database storage of the mails, yet still prevent the overhead of immediate network traffic for every mail. On the downside you'll have to manage an additional daemon and you have to make sure you do not create an open relay.
Yes, set up a queue system by creating a mysql table that holds all necessary information and set a cron job to run every x minutes to select the emails from the queue and send them (don't forget to set a LIMIT for your sql query that fetches the emails for sending).
Db-solution you mention is fine
Simple solution would be to send mail as final action on script (when html has been sent),
Or configure php to use a less bogged down smtp,
http://email.about.com/od/emailprogrammingtips/qt/Configure_PHP_to_Use_a_Remote_SMTP_Server_for_Sending_Mail.htm
regards,
//t
As you said, you won't be sending emails synchronously with your web requests/responses - which is a good idea as you don't want your user experience blocking on something like connecting to a mail server. Even if it's a local mail server, it's always a good idea to make it async and decouple the two. In other words, your mails will be pushed into a queue like mechanism and sent async.
In this case, the advantage of persisting your to-be-sent messages in a database (or some other store) - as opposed to an in memory queue - is that you have more recoverability in case your webserver fails. You can always process persisted emails later, but if you have them in memory, any failure of your webserver process would mean losing the queued mails.