Skip to main content

Understanding Cron Expressions (With Examples)

· 5 min read

Cron expressions schedule recurring jobs, and they are deceptively terse. Five fields and a few symbols control everything, which makes them easy to misread and easy to get subtly wrong. Once you understand the layout and the special characters, they become quick to write and quicker to verify. Paste any expression into the Cron Expression Parser to see in plain English exactly when it will fire.

The five fields

A standard cron expression has five space-separated fields, read left to right:

  • Minute, 0 to 59
  • Hour, 0 to 23, on a 24-hour clock
  • Day of month, 1 to 31
  • Month, 1 to 12
  • Day of week, 0 to 6, where 0 is Sunday

So five fields meaning minute, hour, day-of-month, month, day-of-week. Some systems add a sixth field at the front for seconds or a year at the end, but the classic five-field form is what you will meet most often.

The special characters

Four symbols do most of the work:

  • The asterisk means every value for that field. An asterisk in the hour field means every hour.
  • The comma lists specific values. In the day-of-week field, a list could mean Monday, Wednesday, and Friday.
  • The hyphen defines a range. In the hour field, a range could mean nine through seventeen, every hour from 9 AM to 5 PM.
  • The slash defines a step. A slash with a value in the minute field, starting from zero, means every fifteen minutes.

Some schedulers also use the question mark in the day-of-month or day-of-week field to mean no specific value, which avoids a conflict explained below.

Common schedules by example

  • Every minute: asterisk in all five fields.
  • Every day at midnight: minute zero, hour zero, asterisks for the rest.
  • Every fifteen minutes: a step of fifteen in the minute field, asterisks elsewhere.
  • Weekdays at 9 AM: minute zero, hour nine, asterisk day-of-month, asterisk month, and a range covering Monday through Friday.
  • The first of every month at 6 AM: minute zero, hour six, day-of-month one, asterisk month, asterisk day-of-week.

Build these by setting the most specific fields first and leaving the rest as asterisks.

The gotchas that bite

The day-of-month and day-of-week fields interact in a way that surprises everyone. In most cron implementations, if you specify both fields, the job runs when either condition matches, not both. So setting day-of-month to 1 and day-of-week to Monday does not mean the first Monday; it means the first of the month and every Monday. This is why the question mark exists: you set one field and disable the other to express intent clearly.

Timezones are the other trap. Cron usually runs in the server's local time or in UTC, depending on the system. A job scheduled for 2 AM means 2 AM in whatever zone the scheduler uses, which may not be your zone. Write down which timezone your scheduler runs in before you trust an overnight job.

Daylight saving time compounds this. When clocks spring forward, a job scheduled during the skipped hour may not run at all; when clocks fall back, a job in the repeated hour may run twice. For anything critical, schedule outside the affected early-morning window or use a scheduler that runs in UTC to sidestep DST entirely.

The parser runs entirely in your browser, so you can validate the schedules behind internal jobs without sending anything to a server.

Learn the five fields, the four symbols, and the day-of-week and timezone traps, and cron stops being cryptic.