Using cron to send bulk email on a shared host

  |   By  |  4 Comments

I’m running a conference booking system at and we need to send out lots of emails to delegates and potential delegates. Our host only allows 100 emails per hour from the website, so I needed to find a way of queueing them and sending in batches…

First a mysql db table…

  `to` varchar(500) NOT NULL,
  `from_name` text NOT NULL,
  `from_email` text NOT NULL,
  `copy` text NOT NULL,
  `subject` varchar(500) NOT NULL,
  `message` text NOT NULL,
  `attachment` text NOT NULL,
  `sent` datetime NOT NULL,
  `email_id` int(11) NOT NULL auto_increment,
  PRIMARY KEY  (`email_id`)

I’ve not set up attachments yet, so that table continues everything else we need.

Here’s a function to queue messages

function QueueEmail($to,$subject,$message,$copy,$from_name,$from_email,$attachment)

    $sql="INSERT INTO (`to`,`from_name`,`from_email`,`copy`,`subject`,`message`,`sent`,`attachment`)VALUES('{$sqlsafe['to']}','{$sqlsafe['from_name']}','{$sqlsafe['from_email']}','{$sqlsafe['copy']}','{$sqlsafe['subject']}','{$sqlsafe['message']}',NOW(),'{$sqlsafe['attachment']}')";
    $result=mysql_query($sql) or die(mysql_error());
    if($result) {return TRUE;}else{return FALSE;}

I tend to call it with some basic messaging

echo "

Message to $to queued

"; } else { echo "

Message to $to NOT queued

"; }

So that handles creating messages and storing them in the database queue.

Here’s my cronemail.php file

//email sending script from db queue
define("DB_SERVER", "#");//replace # with server name
define("DB_USER", "#");//replace # with mysql username
define("DB_PASS", "#");//replace # with mysql password
define("DB_NAME", "#");//replace # with db name
// connect to database
$db=mysql_connect(DB_SERVER,DB_USER,DB_PASS)or die("Couldn't connect to database");
mysql_select_db(DB_NAME)or die("Couldn't open database".mysql_error() );

//initialise phpmailer script
$mail = new PHPMailer();
//Grab 80 messages
$sql="SELECT * FROM email ORDER BY email_id LIMIT 0,80";
{//only proceed if emails queued in db 
        $mail->SetFrom($row['from_email'], $row['from_name']);
            $mail->AddAttachment($path, $name = "", $encoding = "base64",$type = "application/octet-stream");
        $mail->Subject = $row['subject'] ;
                //successful send, so delete from DB
                $sql="DELETE FROM email WHERE email_id='".mysql_real_escape_string($row['email_id'])."'";

                mysql_query($sql)or die(mysql_error());
        $mail->ClearAllRecipients();//clears all recipients
        $mail->ClearCustomHeaders();//clears headers for next message
foreach($attachment AS $file)
    unlink($file);//gets rid of uploaded attachments from temporary folder

The code is well commented – make sure you replace the hashes!

You will also need the excellent phpmailer script

Now we need to set up our shared host to execute cronemail.php every hour!

Go to your CPANEL and click on cron jobs – on my version there is a standard link and an advanced link

I use standard!

Common settings gives you some common options – once an hour is what we want (although for testing once every five minutes would be less tedious)

The command to run took a bit longer to get right! A lot of blog posts get this bit wrong!!!

You need to find out your php path – most likely to be /usr/local/bin/php

Then you need the path to the script – best put in a non-public accessable area or in the document root if you must!


So now you can type

/usr/local/bin/php -f /home/(username)/public_html/cronemail.php

into the command to run field and press . The -f tells the php compiler to run the file. Don’t forget to change (username) to your username.

Hope it helps…
Here it is in a zip file with a tester script index.php –emailstuff. Don’t use index.php in a production environment as there is no form checking!


4 comments on “Using cron to send bulk email on a shared host

  1. Excelente tutorial, me ajudou com um perrengue. Eu estava utilizando:
    / Usr / local / bin / php -c / home / (username) / www cronemail.php /
    quando deveria utilizar:
    / Usr / local / bin / php -c / home / (username) / public_html cronemail.php /
    A diferença era o WWW para PUBLIC_HTML libera o acesso aos arquivos para serem anexados também
    Não sei a diferença de -f para -c, só que trava com -f e funfa com o -c

    • Thanks for the excellent tutorial comment, but I don’t speak Spanish! I’m guessing you needed to use public_html in the path which is better anyway. The “www” folder is usually a mirror of “public_html” anyway!

  2. Hi

    An old topic I know! And slightly unrelated but I’d be interested to know where you got the information regarding the emails per hour limit from UK2?

    I’ve been in contact with the support team but they have stated they do not allow mass mails from a shared business hosting account and have so far not divulged the limit per hour, which will obviously exist.

    Any info would be helpful.

    Thanks in advance.


    • Don’t use the word “mass email” with any hosting company – makes you sound like a spammer! I told them what I was sending – booking emails generated by an online booking system.

      The problem with sending email using mail() from UK2 is that their default setting is to send it from the shared server’s IP which will most likely have been blacklisted as spam by other users misuse. So ask for your own IP address (which you would have anyway if you have an ssl on the domain) and then ask them to set mail() to send from your own IP. They told me 100 emails max per hour, when I asked.

Leave a Reply