DEV Community

Fasterhost for FasterHost

Posted on Originally published at fasterhost.in

How to Set Up a Cron Job in cPanel (and Run WP-Cron and Laravel's Scheduler Properly)

First published in the FasterHost knowledge base. FasterHost is an Indian web host; the steps use cPanel's standard Cron Jobs page.

A cron job runs a command on a schedule: process a mail queue every five minutes, clear old files at night, run Laravel's scheduler, or replace WordPress's visitor-triggered cron with a real one. On a cPanel account you add one from a form, without editing a crontab by hand.

When a cron job "doesn't run", it has usually run and failed. Cron starts in your home directory with a minimal environment, not the one your shell has, and most of what follows is about not tripping over that.

The schedule: five fields

┌──────────── minute        (0–59)
│ ┌────────── hour          (0–23)
│ │ ┌──────── day of month  (1–31)
│ │ │ ┌────── month         (1–12)
│ │ │ │ ┌──── day of week   (0–6, 0 = Sunday)
│ │ │ │ │
*/5 * * * *   command
Enter fullscreen mode Exit fullscreen mode

* means "every" and */5 means "every fifth". Ready to copy:

*/5 * * * *    every 5 minutes
*/15 * * * *   every 15 minutes
0 * * * *      every hour, on the hour
30 2 * * *     every day at 2:30 am, server time
0 6 * * 1      every Monday at 6 am
0 0 1 * *      at midnight on the 1st of each month
Enter fullscreen mode Exit fullscreen mode

Cron runs on the server's clock, which may not be your time zone. Run date in a terminal on the server before you schedule anything for a particular hour.

Adding the job in cPanel

  1. Open Cron Jobs. In cPanel, go to Advanced → Cron Jobs. The Cron Email box at the top is where the output of every job is sent. Clear it to stop all of those emails, or silence jobs one at a time (step 4).
  2. Choose when it runs. Under Add New Cron Job, pick a schedule from Common Settings, for example Once Per Five Minutes. It fills in the five fields for you: Minute, Hour, Day, Month and Weekday. You can also type them yourself from the list above.
  3. Write the command with full paths. Spell every path out. To run a PHP script (replace cpuser with your cPanel username):
   /usr/local/bin/php /home/cpuser/public_html/cron.php
Enter fullscreen mode Exit fullscreen mode

To call a URL instead:

   curl -s https://example.in/tasks/run
Enter fullscreen mode Exit fullscreen mode

Run the exact command in a terminal first (cPanel's Advanced → Terminal, or SSH; both need shell access, which not every hosting plan includes). If it fails there, it will fail in cron, where you can't see the error.

  1. Silence it or keep a log. Each run's output is emailed to the Cron Email address, which adds up quickly for a job that runs every five minutes. Append this to discard it:
   >/dev/null 2>&1
Enter fullscreen mode Exit fullscreen mode

Or append it to a log file you can read later. Create the logs folder first:

   /usr/local/bin/php /home/cpuser/public_html/cron.php >> /home/cpuser/logs/cron.log 2>&1
Enter fullscreen mode Exit fullscreen mode
  1. Add it and check it ran. Click Add New Cron Job. It appears under Current Cron Jobs, where you can edit or delete it. After the next scheduled time, read the log file or the email.

Leave enough time between runs for the job to finish. The server starts the next run on schedule even if the last one is still going.

One character to escape: %

In a crontab line, cron turns an unescaped % into a newline and hands everything after it to the command as input (crontab(5)). So a command that works in your terminal, such as one that names its log file after the date, gets cut short under cron. Put a backslash before each %:

/usr/local/bin/php /home/cpuser/public_html/cron.php >> /home/cpuser/logs/cron-$(date +\%F).log 2>&1
Enter fullscreen mode Exit fullscreen mode

Real cron for WordPress

WordPress runs its scheduled tasks only when someone visits the site. On a quiet site a scheduled post can go out late; on a busy one the check runs far more often than it needs to. Turn the visitor trigger off in wp-config.php, above the line that says to stop editing:

define('DISABLE_WP_CRON', true);
Enter fullscreen mode Exit fullscreen mode

Then add a cron job every five minutes (*/5 * * * *), changing the folder if WordPress isn't in public_html:

cd /home/cpuser/public_html && /usr/local/bin/php wp-cron.php >/dev/null 2>&1
Enter fullscreen mode Exit fullscreen mode

Do both. With DISABLE_WP_CRON set and no cron job behind it, nothing runs WordPress's scheduled tasks at all.

Laravel's scheduler

Laravel expects its scheduler to be called every minute, so the schedule is * * * * *:

cd /home/cpuser/app && /usr/local/bin/php artisan schedule:run >/dev/null 2>&1
Enter fullscreen mode Exit fullscreen mode

Your tasks keep their own frequencies inside the app; this one cron entry wakes the scheduler, and Laravel runs whichever tasks are due.

Quick answers

Why is my cron job not running? Most often a path problem: cron starts in your home directory with a minimal environment, so use full paths to PHP and to the script. Run the exact command in a terminal first, and read the job's email or log for the error.

Which time zone does cron use? The server's clock. date shows it; adjust the hour if it differs from yours.

How do I stop cron job emails? Clear the Cron Email address to stop all of them, or end a single job's command with >/dev/null 2>&1.

Top comments (0)