Run cron job in Heroku

cron heroku

You might already be familiar with cron if you have worked on job scheduling. Cron provide easy way to run a job at specified time. The use of cron expression makes it easy to define the interval to run the task. For more flexibility, cron expression can be defined directly in the script instead of crontab and set the cron to execute in every minute which is the minimum interval allowed by cron.

Heroku provides easy way to deploy and run your web application. But, it has its own limitation. It does not allow to use cron jobs. However, there is an alternative way to achieve similar result as cron.

Heroku provides clock process which is one of the process provided by Heroku, the other being web. The clock process allows you to run a script without any limitation on execution time. While the web process timeouts after a certain amount of time, clock process can run indefinitely.

In this tutorial, we will try to imitate the behavior of cron in heroku using clock process.

Define Procfile

We need to define clock process in Procfile to be able to use clock process as follows:

clock: php console.php heroku:schedule:run

If you already has web process defined, the Procfile might look as following:

web: vendor/bin/heroku-php-nginx -C nginx-app.conf public/
clock: php console.php heroku:schedule:run

What this does is that it executes code inside console.php using php command and passes heroku:schedule:run as argument. This is similar to how php file is executed in command line.

Inside console.php, we use the following code:

$appRoot = APP_ROOT;
$cmd = "php $appRoot/console schedule:run";
$outputPath = '/dev/null';
$cmd = "$cmd > $outputPath &";
$sleep = 60; //$input->getOption('sleep');

while (true) {
    exec($cmd);
    sleep($sleep);
}

What this does is that it executes another command in a separate process.

By using while (true), we are running the script indefinitely, and by using sleep, we pause the execution of the script for 60 seconds.

You might wonder why we need to execute the script indefinitely. Well, that’s because the clock process only starts once after the deployment to heroku. If there is no infinite loop, then the script execution stops at a point and the we have to either restart the heroku instance manually or redeploy. This also means that if the clock process stops unintentionally, for example due to error in code, the we have to manually restart or redeploy.

Tags