Xerobit
Dev Productivity

Cron Expression Syntax, Explained by Field

Five fields, nine special characters, a dozen edge cases. A complete reference for cron syntax, minute, hour, day, month, weekday, with annotated real-world examples.

MA Mian Ali Khalid 7 min read
Free tool
Cron Builder
Build and parse cron expressions with human-readable explanations.
Open tool β†’
On this page βŒ„
  1. The five-field format
  2. Field reference
  3. Special characters
  4. The day-of-month / day-of-week OR semantics
  5. Common expression examples
  6. @shorthand aliases
  7. Implementation differences to know
  8. Validating your expression
  9. Further reading

Cron has been running scheduled jobs since 1975. The expression format has barely changed. Yet "cron syntax" is one of the most-Googled things by engineers who write it a dozen times a year, because the field order is counterintuitive, the edge cases are many, and the difference between implementations is silently wrong.

This is the reference you can stop Googling.

The Cron Builder on this site parses any expression and shows the next 10 scheduled runs, the human-readable explanation, and flags implementation differences. Use it while reading this.

The five-field format

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ minute        (0-59)
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ hour          (0-23)
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€ day of month  (1-31)
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€ month         (1-12 or JAN-DEC)
β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€ day of week   (0-7 or SUN-SAT, where 0 and 7 = Sunday)
β”‚ β”‚ β”‚ β”‚ β”‚
* * * * *

A cron expression is executed when all five fields match the current time, with one notable exception for day-of-month / day-of-week (covered below).

Field reference

Minute (0-59)

0      β†’ exactly on the hour
30     β†’ at :30 past each hour
*/15   β†’ every 15 minutes (0, 15, 30, 45)
5,20   β†’ at :05 and :20 past each hour

Hour (0-23)

0      β†’ midnight (12:00 AM)
9-17   β†’ every hour from 9 AM to 5 PM
*/6    β†’ every 6 hours (0, 6, 12, 18)

Day of month (1-31)

1      β†’ first of the month
L      β†’ last day of the month (Quartz, not POSIX/vixie cron)
15,30  β†’ 15th and 30th

Note: months have different lengths. A job scheduled on the 31st won't run in April, June, September, or November. A job on the 29th won't run every February. This is almost always a surprise when it first matters.

Month (1-12 or JAN-DEC)

1      β†’ January (not 0)
*/3    β†’ every quarter (January, April, July, October)
JAN,JUL β†’ January and July (name aliases are case-insensitive in most impls)

Month is 1-indexed. This trips up programmers who are used to 0-indexed months from JavaScript's Date.getMonth().

Day of week (0-7 or SUN-SAT)

0      β†’ Sunday (POSIX/vixie cron)
7      β†’ Sunday (also valid in vixie cron, 0 and 7 are both Sunday)
1      β†’ Monday
5      β†’ Friday
MON-FRI β†’ weekdays

The 0-or-7-for-Sunday quirk exists because the original POSIX spec used 0, but some early implementations also accepted 7, and vixie cron preserved both. Most modern cron implementations accept both. When in doubt, use the named form (SUN) to avoid ambiguity.

Special characters

CharacterMeaningExampleInterpretation
*Any value* * * * *Every minute
,List1,15 (minute)At :01 and :15
-Range9-17 (hour)Hours 9 through 17 inclusive
/Step*/5 (minute)Every 5 minutes
LLastL (day of month)Last day of month (Quartz only)
WNearest weekday15W (day of month)Nearest weekday to the 15th (Quartz only)
#Nth weekday2#3 (day of week)Third Monday (Quartz only)
?No specific value?Used in Quartz for day-of-month or day-of-week when the other is set

The L, W, #, and ? characters are Quartz Scheduler extensions. They do not work in POSIX cron, vixie cron, or most Linux cron implementations. If you're writing crontab entries for a Linux server, stick to * , - /.

The day-of-month / day-of-week OR semantics

This is the most important edge case in all of cron:

If both day-of-month and day-of-week are set (not *), most cron implementations run the job when EITHER condition is true, not both.

0 0 15 * 1    β†’ runs on the 15th of every month
               AND on every Monday, midnight
               (NOT "only on Mondays that are the 15th")

This surprises virtually everyone who writes it for the first time. The intent is usually "the 15th of every month" but the result is "the 15th OR every Monday."

If you want "the 15th of every month only," use:

0 0 15 * *

If you want "the first Monday of each month," you need a workaround, cron doesn't express this natively. Common approaches:

  • Use 0 0 1-7 * 1 (any day from 1-7 that is also Monday): this relies on the OR semantics to coincidentally work, but only because 1-7 covers exactly the first week
  • Use a wrapper script that checks the date inside the job

The Quartz scheduler's ? character exists specifically to handle this: 0 0 15 * ? means "15th of every month, day of week not specified", removing the ambiguity.

Common expression examples

# Every minute
* * * * *

# Every hour, at :00
0 * * * *

# Every day at midnight
0 0 * * *

# Every day at 9 AM
0 9 * * *

# Every weekday at 8 AM
0 8 * * 1-5

# Every Sunday at 2 AM (for maintenance)
0 2 * * 0

# Every 15 minutes
*/15 * * * *

# Every 30 minutes, during business hours weekdays
*/30 9-17 * * 1-5

# First day of every month at midnight
0 0 1 * *

# Every quarter (Jan, Apr, Jul, Oct) on the 1st at midnight
0 0 1 1,4,7,10 *

# Twice a day, at 9 AM and 9 PM
0 9,21 * * *

@shorthand aliases

Most cron implementations support shorthand aliases that expand to standard expressions:

AliasEquivalentMeaning
@yearly or @annually0 0 1 1 *Once a year, January 1st midnight
@monthly0 0 1 * *Once a month, first day midnight
@weekly0 0 * * 0Once a week, Sunday midnight
@daily or @midnight0 0 * * *Once a day, midnight
@hourly0 * * * *Once an hour, at :00
@rebootn/aOnce at system startup

These are vixie cron extensions. They are not part of POSIX cron. They work on most Linux systems (systemd cron, Debian/Ubuntu cron, macOS cron) but not in AWS EventBridge, Kubernetes CronJobs, or Quartz.

Implementation differences to know

FeaturePOSIX/vixiesystemdQuartzAWS EventBridgek8s CronJob
5 fieldsβœ“βœ“6 fields*βœ“βœ“
L, W, #, ?βœ—βœ—βœ“Partialβœ—
Seconds fieldβœ—βœ“βœ“βœ—βœ—
Timezone configPer-user CRON_TZ=Per-unit OnCalendar=Application configSupported1.27+
@rebootβœ“N/Aβœ—βœ—βœ—

*Quartz adds a seconds field at position 0, shifting all others right. Quartz expressions look like 0 0 9 * * ? (second minute hour dom month dow).

Validating your expression

Paste your expression into the Cron Builder. It shows:

  • The human-readable explanation of the schedule
  • The next 10 scheduled run times
  • Which implementation quirks apply

Do this before deploying. A wrong cron expression runs silently, you won't know until the job misses or double-fires.

Further reading

Keep reading

Cron Pitfalls: Timezones, DST, and Missed Runs

Your cron job will run twice or skip entirely when DST changes. Here's why, how UTC solves it, and how to configure timezone-aware schedulers correctly.

AWS EventBridge Scheduler: Cron Schedules for Lambda and AWS Services

AWS EventBridge Scheduler runs Lambda functions, ECS tasks, and other AWS targets on a cron or rate schedule. Learn how to create schedules with cron expressions, handle...

Cron Expression Guide: Syntax, Fields, and Special Characters

Cron expressions schedule recurring jobs using five or six fields: minute, hour, day-of-month, month, day-of-week. Here's the full cron syntax including *, /, -, and ?...

Cron Job Scheduling: How Cron Works and Best Practices

Cron runs scheduled tasks using 5-field time expressions. Learn how cron daemons work, how to manage crontabs, timezone handling, error logging, and alternatives like systemd...

Cron Job Syntax: How to Write and Read Cron Expressions

Cron job syntax is five space-separated fields: minute, hour, day-of-month, month, day-of-week. Here's how to read and write cron expressions, with common schedule examples.

Cron Jobs in Next.js with Vercel Cron: Scheduled Functions

Run scheduled tasks in Next.js using Vercel Cron (serverless cron), GitHub Actions schedules, or Upstash QStash. Includes configuration, securing cron endpoints, and...

Cron Schedule Examples: Common Cron Expressions for Any Interval

Cron expressions schedule recurring jobs. Here's a reference of common cron schedules: every minute, hourly, daily, weekly, monthly, and business hours, with explanations for...

GitHub Actions Scheduled Workflows: cron Syntax and Examples

Schedule GitHub Actions workflows with cron expressions using the schedule trigger. Learn the cron syntax, timezone behavior (UTC only), avoiding missed runs, and examples for...

Kubernetes CronJob: Schedule Recurring Tasks in Kubernetes

Kubernetes CronJob runs containers on a cron schedule inside your cluster. Learn the CronJob spec, concurrency policy, job history limits, timezone support, and debugging...

Related tools

Written by Mian Ali Khalid. More guides in Dev Productivity.