Skip to content
CH SCShop classhosting · beginner · ~30 min · 5 steps

How to set up cron jobs on your server

Schedule commands to run themselves — backups, cache warming, CMS housekeeping — and prove a job actually ran instead of hoping it did.

August 10, 2026 · by Dane Petersen

Cron is the scheduler built into nearly every Linux server: you write down a command and a time, and the server runs it whether or not you’re awake. It’s how backups, cache warming, and CMS housekeeping happen without a human remembering them. You’ll need shell access to your server — if that’s new territory, start with connecting over SSH and come back. The whole lesson is one file and one habit: never trust a cron job you haven’t watched run once.

Open your crontab

Each user account has its own list of scheduled jobs, called a crontab. SSH in and open yours:

crontab -e

The first time, it may ask which editor you want — nano is the friendly answer. To just look without editing:

crontab -l

Learn the five-field schedule syntax

Every job line starts with five fields — minute, hour, day of month, month, day of week — then the command. An asterisk means “every.”

# ┌ minute (0-59)  ┌ hour (0-23)  ┌ day of month  ┌ month  ┌ day of week (0=Sun)
  30               2              *               *        *    command-goes-here

That example is “2:30 a.m., every day.” A few more that cover most real life: 0 * * * * is the top of every hour, */15 * * * * is every fifteen minutes, 0 3 * * 0 is 3 a.m. Sundays. When in doubt, read a line out loud left to right before you save it.

Write the first job with full paths

Cron runs your command in a stripped-down environment — almost none of the PATH your login shell has. This is the number one reason a job “works when I run it by hand” and dies in cron. So spell out full paths, always. Find them with which:

which php

Then write the job using what it printed:

30 2 * * * /usr/bin/php /var/www/example/scripts/nightly.php

Send the output somewhere useful

By default, cron tries to email any output to your server account — a mailbox nobody reads. Give it a real destination instead. At the top of your crontab, set an address for error mail, and on each job, append output to a log file:

MAILTO=you@example.com

30 2 * * * /usr/bin/php /var/www/example/scripts/nightly.php >> /var/log/nightly.log 2>&1

The >> file 2>&1 tail means “append everything, errors included, to this log.” A silent job isn’t a healthy job — it’s an unwitnessed one.

Verify it ran with a one-minute test job

Don’t wait until 2:30 a.m. to find out you typo’d. Add a throwaway job that fires every minute:

* * * * * /bin/date >> /tmp/cron-test.log 2>&1

Save, wait two minutes, then check:

cat /tmp/cron-test.log

Two timestamped lines means cron is running your jobs — remove the test line and trust your real one. If the file never appears, check the system’s own record of what cron did:

grep CRON /var/log/syslog | tail -20

(On Red Hat-flavored servers it’s /var/log/cron; on systemd boxes, journalctl -u cron works too.) You’ll either see your job firing — which points the blame at paths or permissions — or silence, which points at the schedule line itself. Either way you’re verifying with evidence, not hope, and that’s the habit this whole lesson was really about. Where this leads: a backup that takes itself every night.

That's the lesson. Back to the shop for more — or if this is the chore your organization never gets to,that's literally what we're for.