Skip to content
2xKit

Cron Expressions Explained: Reading That Cryptic Five-Field Syntax

How to read a cron string like * * * * * field by field, without memorizing it from scratch every time.

Quick answer

A standard cron expression has five fields, in order: minute, hour, day-of-month, month, and day-of-week, each accepting a specific number, a range, a comma-separated list, an asterisk meaning "every," or a step value like */15 meaning "every 15 units." So `0 9 * * 1-5` means "at minute 0 of hour 9, every day-of-month, every month, on weekdays 1 through 5" — 9 AM Monday through Friday. Decode any cron string in plain English with the Cron Expression Explainer or build one visually with the Cron Expression Generator.

Cron expressions look intimidating mostly because the five fields carry no labels in the string itself, `0 9 * * 1-5` gives no visual hint about what each of the five values means. Once you memorize the fixed field order, though, reading any cron expression becomes a mechanical process rather than a guessing game.

The five fields, in order

A standard cron string always has five space-separated fields in this exact order: minute (0-59), hour (0-23), day-of-month (1-31), month (1-12), and day-of-week (0-6, where 0 is Sunday, though some systems also accept 7 for Sunday). An asterisk `*` in any field means "every value," so `* * * * *` (all asterisks) means "run every single minute."

Beyond a single number or asterisk, each field accepts several useful modifiers: a comma-separated list like `1,15` means "on the 1st and 15th," a range like `9-17` means "every hour from 9 through 17," and a step value like `*/15` in the minute field means "every 15 minutes" (0, 15, 30, 45). These can combine, `*/15 9-17 * * 1-5` means every 15 minutes, during the hours 9 through 17, on weekdays, a common pattern for a business-hours polling job.

Worked examples

`0 0 * * *` means minute 0, hour 0, every day, every month, every day-of-week, which is midnight every day. `0 9 * * 1-5` means minute 0, hour 9, every day-of-month, every month, weekdays only, 9 AM on weekdays. `0 0 1 * *` means minute 0, hour 0, day-of-month 1, every month, every day-of-week, midnight on the first of every month. `*/5 * * * *` means every 5 minutes, all day, every day, one of the most common patterns for frequent background jobs.

Reading unfamiliar cron strings by hand is error-prone precisely because a small misread, mistaking the day-of-month field for the day-of-week field, is easy to do and produces a job that silently runs on the wrong schedule. Pasting a string into the Cron Expression Explainer converts it to a plain-English sentence instantly, and the Cron Expression Generator works the other direction, building the correct syntax from a description so you don't have to hand-assemble the fields.

The day-of-month / day-of-week trap

One genuinely confusing cron behavior: if both the day-of-month and day-of-week fields are restricted (not `*`), most cron implementations treat them as an OR, the job runs if either condition matches, not only when both match simultaneously. A schedule like `0 0 15 * 1` doesn't mean "the 15th, if it's also a Monday," it means "midnight on the 15th of every month, OR every Monday," which surprises people who assume the fields combine with AND logic the way the other three fields do.

Frequently asked questions