Cron Expression Guide: Syntax, Examples, and Common Patterns
Cron is the standard tool for scheduling recurring tasks in Unix-like systems. Despite its age, cron expressions appear everywhere — from server maintenance scripts to AWS Lambda triggers and Kubernetes CronJobs. Understanding the syntax saves time and prevents missed or duplicated jobs.
Test your expressions with our Cron Expression Parser — it translates any cron expression into plain English and shows the next 5 scheduled run times.
The 5-Field Cron Format
Standard cron uses five fields separated by spaces:
┌───────────── minute (0–59)
│ ┌───────────── hour (0–23)
│ │ ┌───────────── day of month (1–31)
│ │ │ ┌───────────── month (1–12)
│ │ │ │ ┌───────────── day of week (0–7, Sunday = 0 or 7)
│ │ │ │ │
* * * * *
Every field can contain:
- A number (exact value)
- An asterisk
*(any value) - A range with
-(e.g.,1-5) - A step with
/(e.g.,*/15) - A list with
,(e.g.,1,3,5)
Special Characters
| Character | Meaning | Example |
|---|---|---|
* | Every value | * * * * * — every minute |
- | Range | 9-17 in hours — 9 AM to 5 PM |
, | List | 1,15 in days — 1st and 15th |
/ | Step | */10 in minutes — every 10 minutes |
Common Cron Expressions
| Expression | Description |
|---|---|
* * * * * | Every minute |
0 * * * * | Every hour (at :00) |
0 0 * * * | Every day at midnight |
0 8 * * * | Every day at 8:00 AM |
0 0 * * 0 | Every Sunday at midnight |
0 0 1 * * | First day of every month at midnight |
*/15 * * * * | Every 15 minutes |
0 */6 * * * | Every 6 hours (midnight, 6 AM, noon, 6 PM) |
30 9 * * 1-5 | Weekdays at 9:30 AM |
0 0 1,15 * * | 1st and 15th of each month at midnight |
0 2 * * 7 | Every Sunday at 2:00 AM |
0 8-18 * * 1-5 | Every hour from 8 AM to 6 PM on weekdays |
Special Strings (Non-Standard)
Many cron implementations support shorthand strings:
| String | Equivalent | Description |
|---|---|---|
@yearly | 0 0 1 1 * | Once a year, January 1 at midnight |
@monthly | 0 0 1 * * | Once a month, first day at midnight |
@weekly | 0 0 * * 0 | Once a week, Sunday at midnight |
@daily | 0 0 * * * | Once a day at midnight |
@hourly | 0 * * * * | Once an hour at :00 |
@reboot | — | Once at system startup |
These are supported in standard cron and crond on Linux, but not in AWS CloudWatch or Kubernetes.
The 6-Field Format
Some platforms extend cron with a seconds field at the beginning:
┌─────────────── second (0–59)
│ ┌───────────── minute (0–59)
│ │ ┌───────────── hour (0–23)
│ │ │ ┌───────────── day of month (1–31)
│ │ │ │ ┌───────────── month (1–12)
│ │ │ │ │ ┌───────────── day of week (0–7)
│ │ │ │ │ │
* * * * * *
Platforms using 6-field format include: Spring Framework, Quartz Scheduler, and some job queue systems. Standard Linux cron uses 5 fields.
Platform Differences
Linux Cron (crontab)
- 5-field format
- Day-of-week values: 0 = Sunday, 7 = Sunday (both accepted)
- Edit with
crontab -e, list withcrontab -l - Does not support seconds field
AWS CloudWatch Events / EventBridge
- Uses a modified 6-field format:
cron(minute hour day-of-month month day-of-week year) - Supports
L(last),W(weekday nearest),#(nth weekday) - Does not support
?in day-of-month and day-of-week simultaneously - Example:
cron(0 12 * * ? *)— every day at noon UTC
Kubernetes CronJob
- Standard 5-field format
- Set timezone with
.spec.timeZone(Kubernetes 1.27+) @yearly,@monthly,@weekly,@daily,@hourlyare supported
GitHub Actions
- Standard 5-field format under
on: schedule: - cron: - Runs in UTC
- Minimum interval: every 5 minutes (GitHub may delay jobs during high load)
Avoiding Common Cron Mistakes
1. Running a job every 5 minutes
# Wrong — this means at minute 5, not every 5 minutes
5 * * * *
# Correct
*/5 * * * *
2. Running a job on the last day of the month
Standard cron does not support “last day of month” directly. A workaround:
# In the cron job script, check if tomorrow is the 1st
0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /path/to/script.sh
AWS CloudWatch supports L for last day: cron(0 23 L * ? *).
3. Timezone confusion
Cron runs in the server’s system timezone by default. This often means UTC on cloud servers, which can cause confusion for jobs intended to run at a specific local time.
# Force UTC in crontab (recommended for production)
CRON_TZ=UTC
0 2 * * * /path/to/backup.sh
# Or set system timezone in crontab
TZ=America/New_York
0 9 * * 1-5 /path/to/morning-report.sh
On Kubernetes 1.27+, use .spec.timeZone: "America/New_York" in the CronJob manifest.
4. Jobs skipping during DST transitions
When clocks “spring forward” (e.g., 2:00 AM becomes 3:00 AM), cron jobs scheduled between 2:00 and 2:59 AM local time are skipped. When clocks “fall back”, jobs in that hour may run twice.
Solution: Schedule critical cron jobs in UTC, outside DST transition windows, or use a DST-aware scheduler.
Cron Expression Testing Checklist
Before deploying a cron job to production:
- Parse it with a tool like our Cron Parser and verify the next 5 run times
- Check that the timezone matches your intent (UTC vs. local)
- Test the script manually before adding it to cron
- Add logging to the cron job command:
command >> /var/log/myjob.log 2>&1 - Consider the first run — should it run immediately or wait until the next scheduled time?
- Verify the user running cron has permission to execute the command and access required files
Debugging Cron Jobs
Cron jobs fail silently by default. Add output redirection to capture logs:
# Redirect stdout and stderr to a log file
0 2 * * * /path/to/script.sh >> /var/log/myjob.log 2>&1
# Send output via email (cron's default if MAILTO is set)
MAILTO=admin@example.com
0 2 * * * /path/to/script.sh
Use journalctl -u cron or grep CRON /var/log/syslog to see cron daemon activity.