Cron expressions pack a lot of power into five (or six) fields separated by spaces. The syntax is compact and efficient, but nobody memorizes all of it. This cheat sheet is the reference you reach for when you need to confirm a character, build a schedule, or quickly understand what an expression does.
Paste any cron expression into the free parser and get an instant plain-English explanation plus next 10 run times.
Try the Free Parser →A standard Unix/Linux cron expression has five fields:
┌─────────────── minute (0–59)
│ ┌───────────── hour (0–23)
│ │ ┌─────────── day of month (1–31)
│ │ │ ┌───────── month (1–12 or JAN–DEC)
│ │ │ │ ┌─────── day of week (0–6 or SUN–SAT, 0=Sunday)
│ │ │ │ │
* * * * *
Tools like Quartz Scheduler, Spring @Scheduled, and some cloud schedulers add a sixth field for seconds at the beginning, making it: second minute hour day-of-month month day-of-week. AWS EventBridge (CloudWatch Events) and GitHub Actions use a slightly different convention — check the platform docs.
| Field | Position | Allowed values | Allowed special chars |
|---|---|---|---|
| Minute | 1st | 0–59 | * , - / |
| Hour | 2nd | 0–23 | * , - / |
| Day of month | 3rd | 1–31 | * , - / ? L W |
| Month | 4th | 1–12 or JAN–DEC | * , - / |
| Day of week | 5th | 0–6 or SUN–SAT (0 = Sunday) | * , - / ? L # |
| Character | Meaning | Example | What it means |
|---|---|---|---|
* |
Any / every value | 0 * * * * | Every hour at :00 |
, |
List of values | 0 9,17 * * * | At 9:00 AM and 5:00 PM every day |
- |
Range of values | 0 9-17 * * * | Every hour from 9 AM to 5 PM |
/ |
Step (every N) | */15 * * * * | Every 15 minutes |
? |
No specific value (day-of-month or day-of-week only) | 0 9 15 * ? | 9 AM on the 15th; day-of-week not specified (Quartz) |
L |
Last — last day of month or last weekday (Quartz) | 0 0 L * ? | Midnight on the last day of every month (Quartz) |
W |
Nearest weekday (Quartz — day-of-month only) | 0 9 15W * ? | 9 AM on the nearest weekday to the 15th (Quartz) |
# |
Nth weekday of month (Quartz — day-of-week only) | 0 9 ? * MON#2 | 9 AM on the 2nd Monday of the month (Quartz) |
* , - / only. The ? L W # characters are Quartz Scheduler extensions and are not valid in Linux crontab. AWS EventBridge has its own cron syntax that differs from both. Always verify against your platform's documentation.
| Expression | Meaning |
|---|---|
| * * * * * | Every minute |
| */5 * * * * | Every 5 minutes |
| */10 * * * * | Every 10 minutes |
| */15 * * * * | Every 15 minutes |
| */30 * * * * | Every 30 minutes |
| 0 * * * * | Every hour (on the hour) |
| 0 */2 * * * | Every 2 hours |
| 0 */4 * * * | Every 4 hours |
| 0 */6 * * * | Every 6 hours |
| 0 */12 * * * | Every 12 hours |
| Expression | Meaning |
|---|---|
| 0 0 * * * | Every day at midnight (00:00) |
| 0 6 * * * | Every day at 6:00 AM |
| 0 9 * * * | Every day at 9:00 AM |
| 0 12 * * * | Every day at noon |
| 0 18 * * * | Every day at 6:00 PM |
| 0 23 * * * | Every day at 11:00 PM |
| 30 2 * * * | Every day at 2:30 AM |
| Expression | Meaning |
|---|---|
| 0 9 * * 1 | Every Monday at 9:00 AM |
| 0 9 * * 1-5 | Every weekday (Mon–Fri) at 9:00 AM |
| 0 9 * * 6,0 | Every weekend (Sat+Sun) at 9:00 AM |
| 0 0 * * 0 | Every Sunday at midnight |
| 0 8 * * MON-FRI | Every weekday at 8:00 AM (using names) |
| Expression | Meaning |
|---|---|
| 0 0 1 * * | First day of every month at midnight |
| 0 0 15 * * | 15th of every month at midnight |
| 0 9 1,15 * * | 1st and 15th of every month at 9 AM |
| 0 0 28-31 * * | Days 28–31 of each month (approximates end-of-month) |
| Expression | Meaning |
|---|---|
| 0 0 1 1 * | January 1st at midnight (once a year) |
| 0 0 1 * 1 | First day of month OR every Monday at midnight (OR logic — see note) |
| 0 9 * JAN,JUL * | 9 AM every day in January and July |
When you specify both a day-of-month value and a day-of-week value (neither is *), cron uses OR logic, not AND. The job runs if either condition is true.
# This runs on the 1st of every month AND on every Monday
# NOT "on the first Monday of every month"
0 9 1 * 1
To target "first Monday of the month," you need application logic or a Quartz-style scheduler that supports the # character (0 9 ? * MON#1).
Most cron implementations accept 3-letter abbreviations in addition to numbers:
| Month numbers | Month names | Day numbers | Day names |
|---|---|---|---|
| 1 | JAN | 0 | SUN |
| 2 | FEB | 1 | MON |
| 3 | MAR | 2 | TUE |
| 4 | APR | 3 | WED |
| 5 | MAY | 4 | THU |
| 6 | JUN | 5 | FRI |
| 7 | JUL | 6 | SAT |
| 8 | AUG | ||
| 9 | SEP | ||
| 10 | OCT | ||
| 11 | NOV | ||
| 12 | DEC |
Names are case-insensitive in most implementations: MON, Mon, and mon are all accepted.
| Platform | Fields | Notes |
|---|---|---|
| Linux crontab | minute hour dom month dow | Standard. No seconds field. ? L W # not supported. |
| Quartz Scheduler (Java) | second minute hour dom month dow [year] | 6–7 fields. Adds ? L W # characters. Widely used in Spring Boot. |
| AWS EventBridge (CloudWatch Events) | minute hour dom month dow year | 6 fields (year required). Uses ? like Quartz. No seconds. |
| GitHub Actions | minute hour dom month dow | Standard 5-field syntax, but always runs in UTC. Minimum interval: 5 minutes. |
| Kubernetes CronJob | minute hour dom month dow | Standard 5-field syntax. No seconds field. |
| Node.js (node-cron) | second minute hour dom month dow | Optional 6-field with seconds at position 1. |
| Python (APScheduler) | Flexible kwargs | Uses named parameters: hour='9', minute='0', day_of_week='mon-fri'. |
Most systems use 0 = Sunday. Some use 0 = Monday. A few accept both 0 and 7 for Sunday. Verify against your platform if weekend/weekday schedules look off.
Cron on a server runs in the server's local timezone (typically UTC). 0 9 * * 1-5 means 9 AM UTC, which may be 5 AM ET or 2 AM PT. Set timezone explicitly if your platform supports it, or calculate the UTC equivalent of your intended local time.
# GitHub Actions — runs at 9 AM ET (UTC-4 during EST / UTC-5 during EST)
# To run at 9 AM ET during standard time (EST = UTC-5):
0 14 * * 1-5 # 14:00 UTC = 9:00 AM EST
*/5 * * * * runs at :00, :05, :10, :15... because it means "every 5th minute of the hour." It does not start counting from when the job was first created.
There is no standard way to schedule "last day of month" in Linux crontab. Common workaround:
# Runs on 28th, 29th, 30th, and 31st — then filter in the script
0 0 28-31 * * /usr/local/bin/check-and-run-if-last-day.sh
If a job takes longer than its interval, multiple instances will run simultaneously. Use flock or a file-based lock to prevent overlap:
*/5 * * * * flock -n /tmp/myjob.lock /path/to/myjob.sh
The / character means "every N, starting from the left value":
| Expression | Equivalent to | Meaning |
|---|---|---|
| */15 (minutes) | 0,15,30,45 | Every 15 minutes |
| 0/15 (minutes) | 0,15,30,45 | Same — starting at 0 |
| 5/15 (minutes) | 5,20,35,50 | Every 15 minutes, starting at :05 |
| */2 (hours) | 0,2,4,6,8,10,12,14,16,18,20,22 | Every even hour |
| 1/2 (hours) | 1,3,5,7,9,11,13,15,17,19,21,23 | Every odd hour |
The fastest way to avoid a misconfigured schedule in production is to test the expression before you commit it. Paste the expression into the free cron parser to see the plain-English description and next 10 run times — it catches timezone issues, OR-logic surprises, and day-numbering mistakes immediately.
Paste any expression and get instant plain-English output + next 10 scheduled run times. No signup required.
Parse a Cron Expression → Get Alerts When Crons Fail →