A cron job is a command or script scheduled to run automatically at a set time or interval on Unix and Linux systems. It is handled by a background service called the cron daemon, which checks every minute for tasks that are due and runs them. Cron jobs are how routine work, backups, log cleanup, report generation, gets done on schedule without anyone lifting a finger.
If you have ever wished a server would just run a task at 2 AM so you do not have to, that is exactly what cron is for. Cron is the time-based job scheduler built into Unix-like operating systems, and it has been quietly automating system work since the 1970s. Once you understand its five-field scheduling syntax, you can automate almost anything that runs from the command line. This guide explains what a cron job is, how to read and write the crontab syntax, how to create and manage jobs, common real-world examples, and the scheduling pitfalls that trip people up.
* (every), , (list), - (range), and / (step).crontab -e to edit, crontab -l to list, crontab -r to remove.Three related terms get used interchangeably, but they each mean something specific:
crond) is the background process that wakes up every minute, checks for scheduled work, and runs whatever is due. You do not interact with it directly.The name itself comes from Chronos, the Greek word for time. Cron is best suited to repetitive, recurring tasks; for a one-time future task, the at command is the better tool.
Every cron job is one line: five time fields that define when, followed by the command that defines what. The five fields always appear in the same order:
* * * * * command-to-run
| | | | |
| | | | +--- Day of week (0-7) (0 and 7 both = Sunday)
| | | +----- Month (1-12)
| | +------- Day of month (1-31)
| +--------- Hour (0-23)
+----------- Minute (0-59)
The cron daemon evaluates each field independently and runs the command when the current time matches all five fields at once. All five fields are mandatory; if you do not care about a particular field, you put an asterisk in it. So reading a real example left to right:
30 2 * * 1 /usr/local/bin/backup.sh
| | | | |
| | | | +-- Monday
| | | +---- every month
| | +------ every day of the month
| +-------- hour 2 (2 AM)
+----------- minute 30
That line runs backup.sh at 2:30 AM every Monday. Once you can read the five fields in order, you can decode any cron schedule.

Raw numbers only get you so far. Four operators let a single field express almost any pattern:
| Operator | Meaning | Example | Result |
|---|---|---|---|
* |
Every value | * * * * * |
Every minute |
, |
List of values | 0 9,17 * * * |
At 9 AM and 5 PM |
- |
Range (inclusive) | 0 9-17 * * * |
Every hour, 9 AM to 5 PM |
/ |
Step value | */15 * * * * |
Every 15 minutes |
You can combine them. 0 0 * * 1-5 runs at midnight on weekdays (Monday through Friday). 0 8,12,17 * * 1-5 runs at 8 AM, noon, and 5 PM on weekdays. The ranges are inclusive on both ends, so 9-17 covers hours 9 through 17.
A note on the extended operators you may see elsewhere (L for last day, W for nearest weekday, # for the nth weekday): these are not part of standard Unix/Linux cron. They belong to other schedulers like Quartz or cloud services such as AWS EventBridge. On a normal Linux server, stick to the four operators above.
Most modern cron implementations support shortcut strings that replace the five-field syntax for common schedules, making your crontab more readable:
| String | Equivalent to | Meaning |
|---|---|---|
@reboot |
n/a | Once, when the system starts up |
@hourly |
0 * * * * |
Top of every hour |
@daily |
0 0 * * * |
Once a day at midnight |
@weekly |
0 0 * * 0 |
Once a week (Sunday midnight) |
@monthly |
0 0 1 * * |
Once a month (1st, midnight) |
@yearly |
0 0 1 1 * |
Once a year (Jan 1, midnight) |
So @daily /usr/local/bin/cleanup.sh is a cleaner way to write 0 0 * * * /usr/local/bin/cleanup.sh. Note that @reboot fires when the cron daemon starts (effectively system boot), not on every daemon restart, and not all implementations support these strings, so check your system if you depend on them.
Each user has their own crontab, and you manage it with the crontab command. There are really only three you use day to day:
crontab -e: Edit your crontab (opens it in your default editor). Add a job, save, and exit. The daemon picks up the change automatically; no restart required.crontab -l: List your current cron jobs. If the output is empty, you have none scheduled.crontab -r: Remove your crontab entirely. Use with care, this deletes all your jobs with no confirmation.A practical workflow: run crontab -e, add a line like 0 2 * * * /path/to/script.sh, save, and you are done. To change a schedule later, run crontab -e again, edit the line, and save.
Worth knowing: a user crontab runs jobs with that user’s permissions. There is also a system-wide crontab (typically /etc/crontab and the /etc/cron.d directory) that administrators use, and it includes an extra field specifying which user runs each command. Access to scheduling can be controlled with the cron.allow and cron.deny files.
Here are patterns you will use constantly, ready to adapt:
| Schedule | When it runs | Typical use |
|---|---|---|
* * * * * |
Every minute | Monitoring or rapid polling (use sparingly) |
*/5 * * * * |
Every 5 minutes | Health checks |
0 * * * * |
Every hour, on the hour | Hourly syncs |
0 2 * * * |
2:00 AM daily | Nightly backups |
0 9 * * 1-5 |
9:00 AM on weekdays | Daily reports (skip weekends) |
0 2 * * 0 |
2:00 AM every Sunday | Weekly maintenance |
0 0 1 * * |
Midnight on the 1st | Monthly reports or billing |
A useful habit: to capture a job’s output (which otherwise gets emailed to the user, or lost), redirect it to a log file. Appending >> /var/log/myjob.log 2>&1 to the command sends both standard output and errors to that file.
This is the single most misunderstood part of cron. When both the day-of-month (field 3) and day-of-week (field 5) are restricted (neither is *), cron treats them as a logical OR, not AND. The job runs when either field matches. So 0 0 13 * 5 does not mean “Friday the 13th”, it means “every 13th of the month and every Friday.” If you need a true AND condition, handle the extra check inside your script.
A few more that cause silent headaches:
date command.:00, so the top of the hour gets crowded. Offsetting a heavy job by a few minutes (e.g. 3 0 * * * instead of 0 0 * * *) can avoid resource contention.This guide describes standard Unix/Linux cron (the Vixie/cronie implementation used by default on most distributions, including Debian, Ubuntu, RHEL, CentOS, and Fedora). Cron syntax, field ranges, operators, special strings, and crontab commands are well-established and consistent across these systems. Some schedulers and cloud platforms (Quartz, AWS EventBridge, Google Cloud Scheduler, and others) use extended or slightly different syntax, including extra fields or additional operators; where behavior can differ, that is noted in the text. Always verify against your own system’s documentation (man 5 crontab) before relying on a schedule in production.
The Industrial Internet of Things (IIoT) is the use of connected sensors and intelligent devices on…
Telemetry is the automated collection and transmission of data from IT systems (servers, networks, applications, and…
Break-fix IT is a reactive support model where a business pays an IT provider only when…
IoT monitoring is the continuous process of collecting and analyzing data from connected devices to keep…