Cron is the time-based job scheduler that has powered Unix and Linux systems since 1975. Nearly half a century later, cron expressions remain the standard way to define recurring schedules — from running backups at midnight to triggering API calls every five minutes. But cron syntax can be notoriously cryptic for newcomers.
This guide demystifies cron expressions completely. You'll learn the field structure, every special character, how different cron variants work (Linux vs. Quartz vs. Spring), and get a cheat sheet of the most common scheduling patterns.
The cron daemon (crond) reads configuration files (crontabs) and executes commands at specified times. Each line in a crontab file contains a cron expression followed by the command to run:
# Run backup script every day at 2:00 AM
0 2 * * * /usr/local/bin/backup.sh
Modern applications have extended cron beyond Linux. Frameworks like Spring (Java), Quartz (Java), Celery Beat (Python), and cloud services like AWS EventBridge all use cron-like syntax for scheduling. Understanding the core syntax gives you a foundation that works everywhere.
A standard Linux cron expression has five fields separated by spaces:
* * * * * │ │ │ │ │ │ │ │ │ └── Day of week (0-7, where 0 and 7 = Sunday) │ │ │ └──── Month (1-12) │ │ └────── Day of month (1-31) │ └──────── Hour (0-23) └────────── Minute (0-59)
Each field accepts specific values:
| Field | Values | Special Characters |
|---|---|---|
| Minute | 0–59 | , - * / |
| Hour | 0–23 | , - * / |
| Day of month | 1–31 | , - * / L W |
| Month | 1–12 or JAN–DEC | , - * / |
| Day of week | 0–7 or SUN–SAT | , - * / L # |
| Symbol | Meaning | Example | Description |
|---|---|---|---|
* | Any value | * * * * * | Every minute of every hour of every day |
, | List separator | 1,15 * * * * | At minute 1 and 15 |
- | Range | 0 9-17 * * * | Every hour from 9 AM to 5 PM |
/ | Step values | */15 * * * * | Every 15 minutes |
L | Last | 0 0 L * * | Last day of month (Quartz only) |
W | Nearest weekday | 0 0 15W * * | Nearest weekday to the 15th (Quartz only) |
# | Nth day of week | 0 0 ? * 6#3 | Third Friday of month (Quartz only) |
Let's look at how these combine in practice:
*/5 * * * * — Every 5 minutes (0, 5, 10, 15, …)0 */2 * * * — Every 2 hours, at minute 0 (0:00, 2:00, 4:00, …)30 4 * * 1-5 — 4:30 AM, Monday through Friday0 0 1,15 * * — Midnight on the 1st and 15th of every month* * * * *Every minute
*/2 * * * *Every 2 minutes
*/5 * * * *Every 5 minutes
*/10 * * * *Every 10 minutes
*/15 * * * *Every 15 minutes
*/30 * * * *Every 30 minutes
0 * * * *Every hour (at :00)
0 */2 * * *Every 2 hours
0 */6 * * *Every 6 hours
0 0 * * *Midnight every day
0 6 * * *Every day at 6:00 AM
0 9 * * *Every day at 9:00 AM
30 14 * * *Every day at 2:30 PM
0 18 * * *Every day at 6:00 PM
0 0 * * 1Every Monday at midnight
0 9 * * 1-5Weekdays at 9:00 AM
0 10 * * 0Every Sunday at 10:00 AM
0 8 * * 1,3,5Mon/Wed/Fri at 8:00 AM
0 0 1 * *First of every month at midnight
0 0 1 */3 *First day of every quarter
0 0 1 1 *January 1st at midnight (yearly)
30 3 15 * *15th of every month at 3:30 AM
0 2 * * 1-5Weekday backups at 2:00 AM
*/5 9-17 * * 1-5Every 5 min during business hours (9–5 weekdays)
0 0 * * 6Weekly cleanup every Saturday at midnight
0 4 1 */2 *Bi-monthly reports on the 1st at 4:00 AM
Java's Quartz Scheduler and many modern tools (Spring, AWS) use an extended cron format with 6 or 7 fields:
* * * * * * [year] │ │ │ │ │ │ │ │ │ │ │ │ │ └── Year (optional, 1970-2099) │ │ │ │ │ └──── Day of week (1-7, 1=SUN or MON-SUN) │ │ │ │ └────── Month (1-12) │ │ │ └──────── Day of month (1-31) │ │ └────────── Hour (0-23) │ └──────────── Minute (0-59) └────────────── Second (0-59)
Key differences from standard cron:
1 (Sunday) instead of 0L (last), W (nearest weekday), and # (Nth weekday)? instead of * for "no specific value" (required when both day-of-month and day-of-week are specified)Examples:
0 0 12 * * ?Every day at 12:00:00 PM
0 30 10 ? * MON-FRIWeekdays at 10:30:00 AM
0 0 0 L * ?Last day of month at midnight
0 0 0 ? * 6#3Third Friday of every month
7 * * * *, 23 * * * *) to prevent thundering herd problems.MAILTO=alerts@example.com.date before scheduling.Cron jobs fail silently more often than you'd expect. Common issues:
/usr/bin/python3 instead of python3.cd in your script or use absolute paths.To check system cron logs:
# Ubuntu/Debian
grep CRON /var/log/syslog
# CentOS/RHEL
cat /var/log/cron
Enter any cron expression to see a human-readable description, next execution times, and a visual schedule — free and instant.
Open Cron Parser →Cron expressions follow a simple pattern — five (or six, or seven) fields defining minute, hour, day, month, and weekday — but the combinations can express virtually any recurring schedule. Mastering the special characters (*, /, -, ,) gives you the vocabulary, and knowing the common patterns gives you fluency. Whether you're scheduling system backups, API polling, or data pipelines, a reliable cron parser tool saves you from counting asterisks and second-guessing your schedules.