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.