Cron expressions pack a full recurring schedule into five terse fields, which makes them compact but genuinely hard to read at a glance until the pattern clicks. This guide breaks down each field, what the special characters actually do, and a reference table of the schedules that come up constantly, so you don’t have to reverse-engineer one from scratch every time.

Key takeaways
  • A standard cron expression has five fields, in order: minute, hour, day of month, month, day of week
  • * means "every value" for that field; a comma lists specific values; a dash defines a range
  • A slash defines a step interval, like */15 for "every 15 units"
  • Day of week runs 0-6 (Sunday to Saturday), though many parsers also accept 7 as an alias for Sunday
  • @daily, @hourly, and similar shortcuts are a common convenience extension, not part of the original five-field spec

The Five Fields, in Order

Every standard cron expression follows the same fixed field order. Getting the order wrong is one of the most common mistakes, since a misplaced value can silently produce a valid-looking expression that runs on a completely different schedule than intended.

Diagram labeling the five fields of a cron expression in order: minute, hour, day of month, month, and day of week
Field order is fixed: minute, hour, day of month, month, day of week.
Field Allowed values
Minute 0-59
Hour 0-23
Day of month 1-31
Month 1-12
Day of week 0-6 (0 = Sunday), or 1-7 depending on the implementation

The Special Characters

Four symbols do almost all the work in cron syntax, and combining them is what makes the format compact.

* (asterisk) — every possible value, no restriction at all in that field.

, (comma) — a list of specific values, for example 1,15 in the day-of-month field means only the 1st and the 15th.

- (dash) — an inclusive range, for example 9-17 in the hour field means every hour from 9am through 5pm.

/ (slash) — a step interval, usually paired with * or a range. */15 in the minute field means every 15 minutes starting at 0; 9-17/2 means every 2 hours within the 9-to-17 range specifically.

Diagram showing */15 in the minute field highlighting which minutes it actually matches: 0, 15, 30, and 45
A step value like */15 selects every 15th unit starting from the field's minimum.

Common Cron Expressions Reference

Schedule Expression
Every minute * * * * *
Every 5 minutes */5 * * * *
Every hour, on the hour 0 * * * *
Every day at midnight 0 0 * * *
Every day at 9:30am 30 9 * * *
Every weekday at 9am 0 9 * * 1-5
Every Monday at 9am 0 9 * * 1
First day of every month at midnight 0 0 1 * *
Every 6 hours 0 */6 * * *
Twice a day, 8am and 8pm 0 8,20 * * *

Convenience Shortcuts

Many, though not all, cron implementations support a handful of named shortcuts that expand to a standard five-field expression:

  • @yearly or @annually0 0 1 1 *
  • @monthly0 0 1 * *
  • @weekly0 0 * * 0
  • @daily or @midnight0 0 * * *
  • @hourly0 * * * *

These are a readability convenience layered on top of the standard fields, not a separate specification, and support for them varies by platform, so it’s worth confirming your specific scheduler accepts the shorthand before relying on it in production.

Building and Checking an Expression Without Guessing

Reading an unfamiliar cron expression correctly, or writing a new one without accidentally scheduling it for the wrong day, is easy to get subtly wrong by hand, especially once ranges and steps combine. The Cron Expression Parser translates a pasted expression into a plain-English description of exactly when it runs, and includes a visual builder mode for constructing one field by field without memorizing the syntax.

The short version

A cron expression is five fields in a fixed order, minute, hour, day of month, month, and day of week, built from four special characters: * for “every value,” , for a list, - for a range, and / for a step interval. The reference table above covers the schedules that come up most often, and the named shortcuts like @daily are a convenience layer that not every platform supports. When in doubt about what an expression actually does, translate it rather than guess, since a single misplaced field can silently point at the wrong day entirely.