Cron Expressions Explained: Complete Syntax Guide
Cron is the time-based job scheduler in Unix-like operating systems. If you need to run a script at midnight, back up a database every Sunday, clear temp files every hour, or send reports on the first of each month, cron is your tool. But its expression syntax — those cryptic strings like 0 */6 * * 1-5 — can be intimidating at first.
This guide demystifies cron expressions completely. You'll learn every field, every special character, see dozens of real-world patterns, and understand the timezone pitfalls that trip up even experienced developers.
Anatomy of a Cron Expression
A standard cron expression has five fields separated by spaces:
┌───────────── minute (0-59) │ ┌─────────── hour (0-23) │ │ ┌───────── day of month (1-31) │ │ │ ┌─────── month (1-12) │ │ │ │ ┌───── day of week (0-6, Sun=0) │ │ │ │ │ * * * * * command to execute
Each field can contain a number, a range, a list, a step value, or a wildcard. Let's break them all down.
The Five Fields in Detail
| Field | Range | Special Characters | Example |
|---|---|---|---|
| Minute | 0-59 | * , - / | */15 (every 15 min) |
| Hour | 0-23 | * , - / | 9-17 (9 AM to 5 PM) |
| Day of Month | 1-31 | * , - / L W | 1,15 (1st and 15th) |
| Month | 1-12 or JAN-DEC | * , - / | 1-6 (Jan through Jun) |
| Day of Week | 0-6 or SUN-SAT | * , - / L # | 1-5 (Mon through Fri) |
Special Characters Explained
- * (asterisk) — matches every value.
* * * * *runs every minute. - , (comma) — specifies a list.
1,3,5in day-of-week means Mon, Wed, Fri. - - (hyphen) — specifies a range.
9-17in hour means 9 AM through 5 PM. - / (slash) — specifies a step.
*/10in minute means every 10 minutes.2/3means starting at 2, every 3rd value. - L (last) — in day-of-month,
Lmeans the last day. In day-of-week,5Lmeans the last Friday. - W (weekday) —
15Wmeans the nearest weekday to the 15th. - # (nth) —
5#3in day-of-week means the 3rd Friday of the month.
Common Cron Patterns
| Expression | Description |
|---|---|
| * * * * * | Every minute |
| */5 * * * * | Every 5 minutes |
| 0 * * * * | Every hour (at minute 0) |
| 0 0 * * * | Every day at midnight |
| 0 9 * * 1-5 | Weekdays at 9 AM |
| 0 0 * * 0 | Every Sunday at midnight |
| 0 0 1 * * | First day of every month |
| 0 0 1 1 * | January 1st (yearly) |
| 30 4 * * * | Every day at 4:30 AM |
| 0 */6 * * * | Every 6 hours |
Use our Cron Expression Generator to build and validate expressions visually.
Working with Crontab
Crontab is the command used to manage your cron schedule:
crontab -e # Edit your crontab
crontab -l # List current entries
crontab -r # Remove all entries (careful!)
sudo crontab -u www-data -e # Edit another user's crontab
Real-World Crontab Examples
# Backup database every night at 2 AM
0 2 * * * /usr/local/bin/backup-db.sh >> /var/log/backup.log 2>&1
# Clear temp files every Sunday at 3 AM
0 3 * * 0 find /tmp -type f -mtime +7 -delete
# Send weekly report every Monday at 9 AM
0 9 * * 1 /opt/scripts/weekly-report.sh
# Renew SSL cert on the 1st and 15th
0 4 1,15 * * certbot renew --quiet
# Health check every 5 minutes
*/5 * * * * curl -s https://example.com/health | logger
Timezone Considerations
Timezone handling is one of the biggest cron gotchas:
- System cron uses the server's timezone. Check with
timedatectlordate. - Cloud services often default to UTC. AWS EventBridge, GCP Cloud Scheduler, and Azure Logic Apps all use UTC unless specified.
- Daylight Saving Time can cause jobs to run twice or skip entirely. A job at 2:30 AM might not run when clocks spring forward.
- Best practice: Run cron in UTC and handle timezone conversion in your scripts. This avoids DST issues entirely.
Debugging Cron Jobs
When cron jobs don't run as expected, check these common issues:
- PATH is different — cron uses a minimal PATH. Always use full paths to commands.
- No output capture — redirect output:
>> /var/log/myjob.log 2>&1 - Permissions — ensure the script is executable:
chmod +x script.sh - Environment variables — cron doesn't load your .bashrc. Define variables in the crontab or script.
- Mail not configured — cron tries to email output. Set
MAILTO=""to suppress.
For complex expressions, validate with our Cron Generator before deploying. You can also format complex data for cron configs using our JSON Formatter when working with cloud scheduler JSON payloads.
Frequently Asked Questions
What is a cron expression?
A cron expression is a string of five fields separated by spaces that defines a schedule. The fields are: minute (0-59), hour (0-23), day of month (1-31), month (1-12), and day of week (0-6). The cron daemon checks these every minute and runs matching jobs.
What does * mean in cron?
The asterisk (*) is a wildcard meaning "every possible value." In the hour field it means every hour; in day-of-month it means every day. Combined across all five fields (* * * * *), it runs every single minute.
How do I run a cron job every 5 minutes?
Use */5 * * * *. The */5 in the minute field means "every 5th minute" — it runs at :00, :05, :10, :15, :20, :25, :30, :35, :40, :45, :50, and :55.
What timezone does cron use?
Traditional system cron uses the server's timezone. Cloud schedulers typically default to UTC. Best practice is to run cron in UTC to avoid Daylight Saving Time issues and handle timezone conversion in your scripts.
What is the difference between cron and crontab?
Cron is the daemon (background service) that executes scheduled commands. Crontab (cron table) is the file listing the schedule entries. Edit with crontab -e, list with crontab -l. Each user has their own crontab.