Cron Expressions Explained: Schedule Tasks Like a Pro
The complete guide to cron expressions. Learn the 5-field syntax, special characters, common patterns, real-world examples, and how to avoid common mistakes.
If you've ever needed to run a script automatically at a specific time - like backing up a database every night or sending a weekly report - you've probably encountered cron. This guide will teach you everything you need to know about cron expressions, from the basics to advanced patterns.
What is Cron?
Cron is a time-based job scheduler built into Unix-like operating systems (Linux, macOS). It runs in the background and executes commands or scripts at scheduled times.
The name "cron" comes from the Greek word "chronos" (time). A cron job is a scheduled task, and a cron expression (also called a cron schedule) defines when that task runs.
Common uses for cron jobs:
- Automated backups
- Sending scheduled emails or reports
- Clearing temporary files
- Syncing data between systems
- Running health checks
- Renewing SSL certificates
Anatomy of a Cron Expression
A standard cron expression has 5 fields separated by spaces:
+--------------- minute (0-59)
| +------------- hour (0-23)
| | +----------- day of month (1-31)
| | | +--------- month (1-12)
| | | | +------- day of week (0-6, where 0 = Sunday)
| | | | |
* * * * *
Each field specifies when the job should run. Let's break down each one:
Field 1: Minute (0-59)
The minute of the hour when the job runs.
| Value | Meaning |
|---|---|
0 | At the top of the hour (XX:00) |
30 | At half past the hour (XX:30) |
*/15 | Every 15 minutes |
0,30 | At :00 and :30 |
Field 2: Hour (0-23)
The hour of the day in 24-hour format.
| Value | Meaning |
|---|---|
0 | Midnight (12:00 AM) |
9 | 9:00 AM |
17 | 5:00 PM |
23 | 11:00 PM |
Field 3: Day of Month (1-31)
The day of the month.
| Value | Meaning |
|---|---|
1 | First day of the month |
15 | 15th of the month |
1,15 | 1st and 15th |
Field 4: Month (1-12)
The month of the year. You can use numbers or three-letter abbreviations.
| Value | Meaning |
|---|---|
1 or JAN | January |
6 or JUN | June |
12 or DEC | December |
1-6 | January through June |
Field 5: Day of Week (0-6)
The day of the week, where Sunday is 0 (or 7 on some systems).
| Value | Day |
|---|---|
0 or SUN | Sunday |
1 or MON | Monday |
2 or TUE | Tuesday |
3 or WED | Wednesday |
4 or THU | Thursday |
5 or FRI | Friday |
6 or SAT | Saturday |
Special Characters Explained
Cron expressions use special characters to create flexible schedules:
Asterisk (*) - Any Value
Matches all possible values for that field.
* * * * * # Every minute of every hour of every day
0 * * * * # Every hour (at minute 0)
0 0 * * * # Every day at midnight
Comma (,) - Multiple Values
Specifies a list of values.
0 9,17 * * * # At 9 AM and 5 PM
0 0 1,15 * * # On the 1st and 15th of each month
0 0 * * 1,3,5 # Every Monday, Wednesday, and Friday
Hyphen (-) - Range of Values
Specifies a range from start to end (inclusive).
0 9-17 * * * # Every hour from 9 AM to 5 PM
0 0 * * 1-5 # Every weekday (Monday through Friday)
0 0 1-7 * * # First 7 days of each month
Slash (/) - Step Values
Specifies intervals. "Start/step" means "starting at start, every step."
*/5 * * * * # Every 5 minutes
0 */2 * * * # Every 2 hours (at :00)
*/10 9-17 * * * # Every 10 minutes during business hours
0 0 */3 * * # Every 3 days
Combining Characters
You can combine these characters for complex schedules:
0,30 9-17 * * 1-5 # At :00 and :30, 9 AM-5 PM, weekdays only
*/15 8-20 * * * # Every 15 min during extended hours
0 6,12,18 1,15 * * # 6 AM, noon, 6 PM on 1st and 15th
Common Cron Patterns
Here are the most frequently used cron expressions:
Every X Minutes
* * * * * # Every minute
*/5 * * * * # Every 5 minutes
*/10 * * * * # Every 10 minutes
*/15 * * * * # Every 15 minutes
*/30 * * * * # Every 30 minutes
Hourly
0 * * * * # Every hour (at :00)
30 * * * * # Every hour (at :30)
0 */2 * * * # Every 2 hours
0 */6 * * * # Every 6 hours (midnight, 6 AM, noon, 6 PM)
Daily
0 0 * * * # Every day at midnight
0 6 * * * # Every day at 6 AM
0 12 * * * # Every day at noon
0 18 * * * # Every day at 6 PM
30 4 * * * # Every day at 4:30 AM
Weekly
0 0 * * 0 # Every Sunday at midnight
0 9 * * 1 # Every Monday at 9 AM
0 0 * * 1-5 # Every weekday at midnight
0 17 * * 5 # Every Friday at 5 PM
0 10 * * 6,0 # Every weekend at 10 AM
Monthly
0 0 1 * * # First day of every month at midnight
0 9 1 * * # First day of every month at 9 AM
0 0 15 * * # 15th of every month at midnight
0 0 1,15 * * # 1st and 15th of every month
0 0 L * * # Last day of every month (if supported)
Yearly
0 0 1 1 * # January 1st at midnight (New Year)
0 0 1 6 * # June 1st at midnight
0 0 25 12 * # December 25th at midnight
Real-World Examples
System Maintenance
# Clear temp files every day at 3 AM
0 3 * * * /usr/local/bin/cleanup-temp.sh
# Rotate logs weekly on Sunday at 2 AM
0 2 * * 0 /usr/sbin/logrotate /etc/logrotate.conf
# Reboot server monthly on the 1st at 4 AM
0 4 1 * * /sbin/reboot
Backups
# Database backup every night at 2 AM
0 2 * * * /scripts/backup-db.sh
# Full backup every Sunday at 1 AM
0 1 * * 0 /scripts/full-backup.sh
# Incremental backup weekdays at 1 AM
0 1 * * 1-5 /scripts/incremental-backup.sh
Reports and Notifications
# Daily report at 8 AM
0 8 * * * /scripts/daily-report.sh
# Weekly summary every Monday at 9 AM
0 9 * * 1 /scripts/weekly-summary.sh
# Monthly invoice on the 1st at 6 AM
0 6 1 * * /scripts/generate-invoices.sh
Application Tasks
# Check for updates every 6 hours
0 */6 * * * /app/check-updates.sh
# Sync data every 15 minutes during business hours
*/15 9-17 * * 1-5 /app/sync-data.sh
# Send digest email every evening at 6 PM
0 18 * * * /app/send-digest.sh
# Expire sessions every hour
0 * * * * /app/expire-sessions.sh
SSL and Security
# Renew SSL certificates (weekly check)
0 3 * * 1 certbot renew --quiet
# Security scan every night at 1 AM
0 1 * * * /scripts/security-scan.sh
# Update virus definitions every 4 hours
0 */4 * * * freshclam
Extended Cron Syntax
Some systems support additional fields and features:
6-Field Cron (with Seconds)
Some schedulers (like Quartz, Spring, node-cron) support seconds as the first field:
+---------------- second (0-59)
| +-------------- minute (0-59)
| | +------------ hour (0-23)
| | | +---------- day of month (1-31)
| | | | +-------- month (1-12)
| | | | | +------ day of week (0-6)
| | | | | |
* * * * * *
*/30 * * * * * # Every 30 seconds
0 */5 * * * * # Every 5 minutes (at :00 seconds)
0 0 * * * * # Every hour (at :00:00)
7-Field Cron (with Year)
Some enterprise schedulers add a year field:
0 0 1 1 * 2025 # January 1, 2025 at midnight
Special Strings
Many cron implementations support convenient shortcuts:
| String | Equivalent | Description |
|---|---|---|
@yearly or @annually | 0 0 1 1 * | Once a year (Jan 1, midnight) |
@monthly | 0 0 1 * * | Once a month (1st, midnight) |
@weekly | 0 0 * * 0 | Once a week (Sunday, midnight) |
@daily or @midnight | 0 0 * * * | Once a day (midnight) |
@hourly | 0 * * * * | Once an hour (at :00) |
@reboot | N/A | Once at startup |
Common Mistakes to Avoid
1. Forgetting About Timezones
Cron runs in the server's timezone, which might differ from your local time.
# If your server is in UTC but you want 9 AM EST:
# EST is UTC-5, so use hour 14 (9 + 5)
0 14 * * * /scripts/morning-task.sh
Tip: Use timedatectl to check your server's timezone.
2. Day of Month AND Day of Week Confusion
When you specify both day of month AND day of week, cron runs when EITHER condition is met (OR logic), not both (AND logic).
# This runs on the 15th AND every Friday, not "15th if it's Friday"
0 0 15 * 5 /scripts/task.sh
# To run only on the 15th, ignore day of week:
0 0 15 * * /scripts/task.sh
3. Not Escaping Special Characters
In crontab, the percent sign (%) has special meaning (newline). Escape it:
# Wrong - % will break this
0 0 * * * echo "Today is $(date +%Y-%m-%d)"
# Correct - escape the %
0 0 * * * echo "Today is $(date +\%Y-\%m-\%d)"
4. Not Using Full Paths
Cron runs with a minimal environment. Always use absolute paths:
# Wrong - might not find the command
0 * * * * node /app/script.js
# Correct - use full path
0 * * * * /usr/bin/node /app/script.js
5. Overlapping Jobs
If a job takes longer than its interval, instances can pile up:
# If backup takes 10 minutes but runs every 5...
*/5 * * * * /scripts/long-backup.sh # Problem!
# Use flock to prevent overlapping
*/5 * * * * /usr/bin/flock - n /tmp/backup.lock /scripts/long-backup.sh
How to Set Up Cron Jobs
Editing Your Crontab
# Edit your user's crontab
crontab - e
# View your crontab
crontab - l
# Remove all cron jobs
crontab - r
Crontab File Format
Each line in a crontab follows this format:
# Comment lines start with #
MAILTO="you@example.com" # Optional: email output
# m h dom mon dow command
0 5 * * * /scripts/backup.sh
*/15 * * * * /scripts/monitor.sh
System-Wide Cron
System cron jobs include a user field:
# /etc/crontab or files in /etc/cron.d/
# m h dom mon dow user command
0 5 * * * root /scripts/backup.sh
Logging Output
Capture output for debugging:
# Log both stdout and stderr
0 * * * * /scripts/task.sh >> /var/log/task.log 2>&1
# Discard output (silent)
0 * * * * /scripts/task.sh > /dev/null 2>&1
Testing Cron Expressions
Before deploying, always verify your expression means what you think:
- Use online tools - Our Cron Expression Builder shows the next scheduled runs
- Check with
systemctl- View recent runs:systemctl status cron - Test with short intervals - Start with
* * * * *(every minute) to verify the job works
Quick Reference
| Schedule | Expression |
|---|---|
| Every minute | * * * * * |
| Every 5 minutes | */5 * * * * |
| Every hour | 0 * * * * |
| Every day at midnight | 0 0 * * * |
| Every day at 9 AM | 0 9 * * * |
| Every Monday at 9 AM | 0 9 * * 1 |
| Weekdays at 9 AM | 0 9 * * 1-5 |
| First of month at midnight | 0 0 1 * * |
| Every Sunday at midnight | 0 0 * * 0 |
| Every 6 hours | 0 */6 * * * |
| Twice daily (9 AM and 6 PM) | 0 9,18 * * * |
Key Takeaways
- Five fields: minute, hour, day of month, month, day of week
- Special characters:
*(any),,(list),-(range),/(step) - Always use absolute paths in cron commands
- Mind the timezone - cron uses server time
- Test before deploying - verify the schedule is correct
- Log output - makes debugging much easier
- Prevent overlaps - use
flockfor long-running jobs
Use our Cron Expression Builder to create, validate, and understand cron expressions visually.
Related Tools
Related Articles
Try Our Free Tools
200+ browser-based tools for developers and creators. No uploads, complete privacy.
Explore All Tools