Cron Jobs Explained: The Developer's Complete Guide to Task Scheduling
TL;DR
Every production server has a hidden heartbeat: cron. From daily backups to hourly API syncs, cron jobs are the unsung automation engine of the internet. This is the guide you wish you had on day one.
Table of Contents
Every production server has a hidden heartbeat. It wakes up at midnight, runs your database backups, cleans up temp files, sends your weekly report emails, and goes back to sleep — without you ever touching a keyboard. That heartbeat is called cron. And if you are deploying to any Linux/Unix server and don't understand it deeply, you are leaving a massive automation superpower on the table.
In this guide, we will dissect every part of a cron expression, show you 10 real-world scheduling patterns, expose the 5 mistakes that will burn you in production, and teach you how to debug cron jobs like a seasoned sysadmin. You can also use our free Crontab Generator to build and validate any expression visually without memorizing the syntax.
1. The Cron Syntax: All 5 Fields Explained
A cron expression is a string of five fields separated by spaces. Each field controls a unit of time. Together they define a precise, repeating schedule.
| Field | Position | Allowed Values | Example |
|---|---|---|---|
| Minute | 1st | 0 – 59 | 30 |
| Hour | 2nd | 0 – 23 | 14 (= 2 PM) |
| Day of Month | 3rd | 1 – 31 | 15 |
| Month | 4th | 1 – 12 | 6 (= June) |
| Day of Week | 5th | 0 – 6 (Sun=0 or 7) | 1 (= Monday) |
2. Special Characters: The Powers Behind the Schedule
The asterisk * is just the beginning. Cron's real flexibility comes from four special characters that let you express complex schedules in a single string.
- *Asterisk — "Every"Matches all possible values.
* * * * *means "every minute of every hour of every day." - ,Comma — "And"Specifies a list.
0 9,12,18 * * *runs at 9 AM, noon, and 6 PM daily. - -Hyphen — "Through"Defines a range.
0 9-17 * * 1-5runs at the top of every hour, Monday through Friday, 9 AM to 5 PM. - /Slash — "Every N-th"Specifies step intervals.
*/15 * * * *runs every 15 minutes.0 */6 * * *runs every 6 hours.
3. @Macros: The Shorthand Commands
Most modern cron implementations support @macros — human-readable shortcuts that replace the 5-field syntax entirely. They are especially useful for common schedules.
| Macro | Equivalent | When It Runs |
|---|---|---|
| @reboot | — | Once at system startup |
| @yearly / @annually | 0 0 1 1 * | Jan 1st at midnight |
| @monthly | 0 0 1 * * | 1st of every month at midnight |
| @weekly | 0 0 * * 0 | Every Sunday at midnight |
| @daily / @midnight | 0 0 * * * | Every day at midnight |
| @hourly | 0 * * * * | At the start of every hour |
4. 10 Real-World Cron Job Examples
Theory is one thing. Here are the scheduling patterns you will actually encounter in production systems.
| # | Use Case | Cron Expression | Schedule |
|---|---|---|---|
| 1 | Database Backup | 0 2 * * * | Every day at 2 AM |
| 2 | Clear Cache Files | */30 * * * * | Every 30 minutes |
| 3 | Send Weekly Report | 0 8 * * 1 | Monday mornings at 8 AM |
| 4 | Sync API Data | 0 */4 * * * | Every 4 hours |
| 5 | SSL Cert Renewal | 0 3 * * 0 | Every Sunday at 3 AM |
| 6 | Generate Sitemap | 0 1 * * * | Every day at 1 AM |
| 7 | Send Digest Emails | 0 7 * * 1-5 | Weekdays at 7 AM |
| 8 | Delete Temp Files | 0 0 * * 0 | Every Sunday at midnight |
| 9 | Monthly Invoice Run | 0 9 1 * * | 1st of every month at 9 AM |
| 10 | Start Service on Boot | @reboot | At every system restart |
5. The 5 Most Common Cron Job Mistakes (And How to Fix Them)
Cron issues are notoriously silent and frustrating to debug. These are the five traps that catch nearly every developer at least once.
- 1Wrong Working Directory
Cron does not inherit your shell's current directory. If your script does
require '../config.php', it will fail silently because cron runs from/or the user's home directory. Fix: Always use absolute paths, or setcd /path/to/project &&before your command. - 2Missing Environment Variables
Cron uses a minimal environment — no
PATH,HOME, or custom env vars you set in.bashrc. Commands likephporpython3may not be found. Fix: Use the full binary path (e.g.,/usr/bin/phpor/usr/local/bin/python3), or setPATHat the top of your crontab. - 3No Output Logging
By default, cron emails output to the system. If mail is not configured, all output is silently discarded. You will never know if your job failed. Fix: Redirect output:
* * * * * /path/to/script.sh >> /var/log/myjob.log 2>&1 - 4Overlapping Job Runs
Cron does not know if the previous run of a job is still executing. A job scheduled every minute that takes 90 seconds will have two instances running simultaneously, potentially corrupting data. Fix: Use
flock:* * * * * flock -n /tmp/myjob.lock /path/to/job.sh - 5DST and Timezone Confusion
Cron runs in the system's timezone by default. Daylight Saving Time transitions can cause a job to run twice (or not at all) at 2 AM. Fix: Set an explicit timezone in your crontab using
CRON_TZ=UTCat the top of the file, or use UTC for all critical jobs.
6. How to Monitor and Debug Cron Jobs
Debugging cron is all about making the invisible visible. Here is your debugging toolkit.
View Cron Logs
On Debian/Ubuntu systems, cron logs to syslog. View them with:
# View recent cron executions grep CRON /var/log/syslog | tail -50 # Or on systems using journald journalctl -u cron --since "1 hour ago"
Redirect Output to a Log File
The simplest and most reliable debugging method — always log stdout and stderr:
# Redirect both stdout and stderr to a timestamped log */5 * * * * /usr/bin/php /var/www/job.php >> /var/log/cron_job.log 2>&1 # Prepend timestamps using ts from the moreutils package */5 * * * * /usr/bin/php /var/www/job.php 2>&1 | ts >> /var/log/cron_job.log
Use MAILTO for Error Alerts
Set a MAILTO variable at the top of your crontab to receive email on any output:
MAILTO=admin@yoursite.com # Job output will be emailed if it produces any output 0 2 * * * /usr/bin/php backup.php
Test Your Command Manually First
Before scheduling anything, run the exact command as the cron user (usually root or www-data) to ensure it works in the same environment:
# Test as the www-data user (common for web server crons) sudo -u www-data /usr/bin/php /var/www/html/job.php
Build & Validate Your Cron Expression
Not sure if your expression is right? Use our free visual Crontab Generator to build any schedule, see the human-readable description, and copy the final expression instantly.
Open Crontab GeneratorFrequently Asked Questions
How do I run a cron job every 5 minutes?
Use the step operator: */5 * * * * /path/to/command. The */5 in the minute field means "every 5th minute" — so it runs at :00, :05, :10, :15, and so on.
How do I edit my crontab?
Run crontab -e in your terminal. This opens your personal crontab in your default text editor. Use crontab -l to list existing jobs, and crontab -r to delete all jobs (use caution!).
Why is my cron job not running?
The most common reasons are: (1) The cron service is not running — check with systemctl status cron. (2) Your command uses relative paths. (3) The script is not executable — run chmod +x /path/to/script.sh. (4) Environment variables (like PATH) are missing. Start debugging by redirecting output to a log file.
What is the difference between cron and crontab?
cron is the Linux daemon (background service) that reads schedules and executes commands. crontab (cron table) is the configuration file that lists the jobs and their schedules. Each user on the system can have their own crontab, plus there is a system-wide crontab at /etc/crontab.
Can I run a cron job every second?
No — cron's minimum resolution is one minute. If you need sub-minute scheduling, consider using a persistent process with an internal sleep loop, or tools like systemd timers, which support second-level precision.
How do I schedule a cron job to run on weekdays only?
Use the day-of-week field with a range: 0 9 * * 1-5 runs at 9 AM, Monday through Friday. 1=Monday, 5=Friday. Alternatively, 0 9 * * MON-FRI works in most cron implementations that support day name abbreviations.
What happens if my server is off when a cron job is scheduled to run?
Standard cron simply skips the missed job — it does not backfill. If you need missed tasks to run when the server comes back online, look into anacron (which is designed for systems that do not run 24/7) or task queue systems like Celery Beat or Laravel Scheduler, which have built-in catch-up logic.
Was this article helpful?
Comments
Loading comments...