Host Cron Jobs: Correct Scheduling and Troubleshooting

Set up your host cron job correctly: absolute PHP path, scheduling syntax, capturing output for debugging, and the mistakes that stop it from running.

6 min Updated 26 Sep 2026

You've saved the cron job, waited, and nothing happened. No email arrived, no file was created, no record was added to the database. This is exactly the moment when you need to understand how a host cron job runs and why it stays silent. The problem is almost always one of three things: a wrong path, incorrect scheduling syntax, or output that goes nowhere and you never see it.

The absolute PHP path; where most cron jobs die

In the control panel, you fill the Command field with php /home/user/public_html/cron.php and think you're done. You're not. Cron runs in an environment whose PATH differs from your interactive shell. php may not be found at all, or a version may be found that isn't the same version your site runs on.

First, find the real path to the binary:

which php
# /usr/local/bin/php
php -v
# PHP 8.2.18 (cli)

Then write that absolute path in the Command:

/usr/local/bin/php /home/username/public_html/cron.php

If your site runs on PHP 8.2 and the CLI is on 7.4, your script may die with a parse error and you'll never see that error. This version mismatch is one of the most common reasons for "it works but produces no result."

Why a relative path doesn't work

Cron runs with the working directory set to $HOME, not the script's directory. If you've used require 'config.php' in your code, the file won't be found. Always give an absolute path, or call chdir(__DIR__) first.

Scheduling syntax: five stars that everyone misreads

The standard format has five fields: minute, hour, day of month, month, day of week. Keep the order and for "every five minutes" write */5 * * * *. For "every night at 3 AM" write 0 3 * * *.

ExpressionMeaningCommon use
*/5 * * * *Every 5 minutesLightweight sync
0 * * * *Top of every hourCache cleanup
0 3 * * *Every day at 3 AMDatabase backup
0 0 1 * *First of every monthMonthly report
0 4 * * 0Sundays at 4 AMWeekly update

A point that's rarely mentioned: the day-of-month and day-of-week fields are OR'd together, not AND'd. If you write 0 0 1 * 0, the script runs both on the first of the month and every Sunday. If you want it to run only on the first of the month when it's a Sunday, you have to check the condition inside your code.

This is where they go wrong

The biggest mistake I've seen is this: a user sets the schedule to * * * * * to "test quickly," then forgets to change it back. The sign is obvious too; the server log fills up with repeated entries, host resource usage climbs, and the site slows down. If you don't know the resource limits, before any testing read the complete reference of hosting resource limits so you understand what each number counts.

Capture the output, or you're flying blind

By default, cron emails the output to you, but this email often goes to spam or isn't sent at all. The more reliable way is to redirect the output to a file:

/usr/local/bin/php /home/username/public_html/cron.php >> /home/username/cron.log 2>&1

Now 2>&1 makes stderr errors land in the same file. If the file stays empty, it means the script ran and produced no error. If the file isn't created at all, it means cron never reached that line and the problem is in the path or the schedule.

For long-running scripts, also add a file lock so concurrent runs don't happen:

*/10 * * * * /usr/bin/flock -n /tmp/mycron.lock /usr/local/bin/php /home/username/public_html/cron.php >> /home/username/cron.log 2>&1

Without this lock, if the previous run hasn't finished yet, the next one hits the same database and creates duplicate records. I've seen this a lot in API syncs.

Shared hosting cron jobs vs. a dedicated server

On shared hosting, cron runs in a restricted environment. The number of concurrent runs is limited and heavy scripts may be cut off mid-way. If your work is image processing, a heavy import, or scanning thousands of records, this environment isn't the right place.

There's a real choice here. For light, periodic tasks, the same shared hosting is enough and it's simpler to manage. For heavy processing or running every minute, migrate to a dedicated server or VPS; there you have full control and can also use a systemd timer instead of cron, which has better logging and error handling. For anything running under a minute, I prefer systemd.

Take the concurrent-run limit seriously

If you stack several heavy cron jobs on top of each other, you may hit the Entry Process ceiling and the site becomes slow or unresponsive for visitors. We've covered the difference between this concept and normal visits in the explanation of Entry Process and how it differs from a visit. The simple solution: spread out the schedules. One at 2, one at 3, one at 4.

Troubleshooting checklist when cron doesn't run

  1. Confirm the absolute path to the PHP binary with which php.
  2. Write the full absolute path to the script file.
  3. Redirect the output to a file and, after one cycle, read the file.
  4. Run the script manually from SSH: /usr/local/bin/php /home/username/public_html/cron.php. If it doesn't work manually either, the problem isn't cron, it's the code.
  5. Check the file permissions; the file must be readable by the hosting user.
  6. If the script connects to a database, use localhost, not the public IP.

Take step four seriously. Half the tickets that reach us turn out, after a manual run, to be a script that had a code error from the start, and cron was innocent. If you're getting a PHP error, the guide on fixing the white screen and debugging PHP is a good starting point.

Cron for WordPress and common tasks

WordPress has its own internal scheduling system (WP-Cron) that's triggered by a user visit. If the site's traffic is low, this system runs late. The standard solution is to disable WP-Cron and call it with a real cron job:

# in wp-config.php
define('DISABLE_WP_CRON', true);

# in the cron job
*/15 * * * * /usr/local/bin/php /home/username/public_html/wp-cron.php >> /home/username/cron.log 2>&1

For database backups, don't run mysqldump directly either; first write the output to a temporary file and then compress it, otherwise with large databases you'll hit the memory ceiling.

If you've just brought up your site and aren't yet comfortable with the folder structure, the guide to uploading your site to hosting clarifies the paths. For network and DNS tests, the free webmaster tools make the job faster.

If you're working on Linux hosting, the Cron Jobs section in the control panel is where you enter these lines; just remember to check the output once after every change.

Frequently asked questions

Why does the cron job run but I see no result?

It almost always comes down to the script running but throwing an error, and the error not being logged anywhere. Redirect the output to a file with >> /home/username/cron.log 2>&1 and, after a full cycle, read the file. If the file is empty, the script ran without errors and the problem is in the code logic or the database connection.

How do I find the PHP path for a cron job?

With the which php command in SSH. The output is usually something like /usr/local/bin/php. Write that same absolute path in the Command field. If the CLI version differs from the version your site runs on, check with php -v and, if needed, give the path to the correct version.

Can I run a cron job every minute?

Technically yes, but on shared hosting I don't recommend it. Running every minute consumes resources, and if the script is heavy you'll hit the Entry Process ceiling and the site slows down. For truly time-sensitive tasks, a dedicated server or VPS is the better choice.

What's the difference between WP-Cron and a server cron job?

WP-Cron is triggered on every user visit, so on low-traffic sites it runs late or not at all. A server cron job runs independently of visits and according to your schedule. For serious sites, disable WP-Cron and call it with a real cron job.

Do one thing right now: redirect the cron output to a file and wait one cycle. Until you see that file, any other change is just guesswork.

Was this page helpful?