Schedule tasks with cron jobs
Websites often need to do work on a schedule: send newsletters, clear old data, check for updates or create reports. On Linux servers this is done with cron, a built-in scheduler that runs a command at the times you choose. A single scheduled command is called a cron job. This guide explains how to write the schedule, run a PHP script, keep a log, and set up WordPress to use a real cron job.
Where to add cron jobs
On web hosting, cron jobs are usually added in a section of your hosting control panel or account for scheduled tasks. The exact place depends on your host. On a VPS or cloud server, or if your hosting includes SSH access, you can edit your list of cron jobs, called the crontab, with:
crontab -e
crontab -l shows the current list.
Cron syntax: five time fields
Each cron job is one line: five time fields followed by the command to run.
┌───────── minute (0–59)
│ ┌─────── hour (0–23)
│ │ ┌───── day of the month (1–31)
│ │ │ ┌─── month (1–12)
│ │ │ │ ┌─ day of the week (0–7, where 0 and 7 are both Sunday)
│ │ │ │ │
* * * * * command to run
Each field accepts:
*for every value- a single number, such as
5 - a list, such as
1,15 - a range, such as
1-5 - a step, such as
*/15for every 15th value
When both the day of the month and the day of the week are set (neither is *), the job runs when either one matches.
Examples
| Schedule | Meaning |
|---|---|
0 3 * * * | Every day at 03:00 |
*/15 * * * * | Every 15 minutes |
30 6 * * 1-5 | 06:30, Monday to Friday |
0 0 1 * * | Midnight on the first day of each month |
0 2 * * 0 | Every Sunday at 02:00 |
Run a PHP script
To run a PHP script, give the path to PHP and the full path to the script. Use full paths, because cron runs with a minimal environment and may not find programs or files otherwise.
0 3 * * * /usr/bin/php /home/exampleuser/scripts/cleanup.php
The path to PHP varies between servers, and some hosts offer several PHP versions at different paths. Run which php over SSH, or check your host's documentation, to find the right one.
Store scripts that only cron should run outside your website's document root, so visitors cannot start them from a browser.
Log the output
By default, cron may try to email a job's output to the account owner, or the output may simply be lost. Writing it to a log file makes problems easier to find:
0 3 * * * /usr/bin/php /home/exampleuser/scripts/cleanup.php >> /home/exampleuser/logs/cleanup.log 2>&1
>> adds the output to the end of the log file, and 2>&1 includes error messages too. Create the logs folder first, and check the log size now and then, since it grows with each run.
If you do not need any output, send it to /dev/null instead:
0 3 * * * /usr/bin/php /home/exampleuser/scripts/cleanup.php > /dev/null 2>&1
Replace WordPress wp-cron with a real cron job
WordPress has its own scheduler, wp-cron. It does not run on a timer. Instead, it checks for due tasks when someone visits the site. On a quiet site, scheduled posts and updates may run late; on a busy site, the checks happen on many page loads and add extra work.
A real cron job fixes both problems.
-
Take a backup of your
wp-config.phpfile. -
Add this line to
wp-config.php, above the line that says to stop editing:define( 'DISABLE_WP_CRON', true ); -
Add a cron job that calls
wp-cron.phpon a schedule, for example every 15 minutes:*/15 * * * * curl -s https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1 -
Check over the following hours that scheduled tasks still run, for example by scheduling a test post.
If your host provides WP-CLI, the WordPress command-line tool, you can run wp cron event run --due-now with the --path option pointing to your WordPress folder instead of calling the address.
Time zones
Cron uses the server's time zone, which is often UTC and may differ from yours and from the time zone set in your website app. Check the server's time with the date command over SSH, or ask your host, before scheduling jobs that must run at a certain local time.
Keep jobs light
- Don't run jobs more often than needed. A job every minute runs 1,440 times a day. Most maintenance tasks are fine hourly or daily.
- Spread jobs out. Avoid starting several heavy jobs at the same minute, such as midnight.
- Prevent overlaps. If a job can take longer than the gap between runs, copies can pile up and use your account's resources. Lengthen the interval, or use a lock tool such as
flockwhere available. - Remove jobs you no longer need, for example after removing a plugin.
Frequent or heavy jobs count toward your hosting account's resource limits, see Resource limits on shared hosting.