Skip to content
WebTricks

Cron expression explainer

Translate a cron expression into plain English so you can read schedules at a glance. Runs in your browser.

At 09:00 AM, Monday through Friday

Examples

Fields: minute · hour · day-of-month · month · day-of-week

What this cron explainer does

Paste a cron expression and the tool renders it as a plain-English sentence, such as “At 09:00 AM, Monday through Friday”, so you can check a schedule before it ships to a crontab, a CI workflow or a serverless scheduler. Parsing happens in your browser with the cronstrue library, the same one many dashboards use. The explainer understands the standard five-field syntax plus the optional seconds field, month and weekday names, and the Quartz extensions (L, W, #, ?). It validates as you type and shows the parser’s error for anything malformed.

How to use it

  1. Type or paste into Cron expression. The English translation appears immediately; an invalid expression turns the field red and shows the error.
  2. Click an Examples button (weekdays at 9am, every 15 minutes, first of the month, and so on) to load a known-good schedule and edit from there.
  3. Keep the field order in mind, shown under the input: minute, hour, day-of-month, month, day-of-week.

Field reference

PositionFieldAllowed valuesSpecial characters
1minute0-59* , - /
2hour0-23* , - /
3day of month1-31* , - / L W
4month1-12 or JAN-DEC* , - /
5day of week0-7 or SUN-SAT (0 and 7 are Sunday)* , - / L #
  • * every value
  • a,b,c list, for example 1,15 for the 1st and 15th
  • a-b inclusive range, for example MON-FRI or 9-17
  • */n every n-th value; a/n every n-th starting at a
  • L last (day of month, or last weekday as in 5L for last Friday); W nearest weekday; n#k the k-th weekday n, such as 1#2 for the second Monday. These three are Quartz and Jenkins syntax and are rejected by classic Vixie cron and systemd timers.

Examples

ExpressionMeaning
* * * * *every minute
*/5 * * * *every 5 minutes
0 * * * *every hour, on the hour
0 0 * * *daily at midnight
0 9 * * 1-5weekdays at 09:00
30 3 * * 6Saturdays at 03:30
0 0 1 * *first day of every month at midnight
0 0 1 1 *once a year, 1 January
0 */6 * * *every 6 hours (00:00, 06:00, 12:00, 18:00)
0 9,17 * * *twice a day, 09:00 and 17:00
0 0 * * 0Sundays at midnight
15 2 L * *02:15 on the last day of the month (Quartz syntax)

Many daemons also accept shorthand aliases: @hourly, @daily, @weekly, @monthly, @yearly and @reboot. The first five map to the expressions above; @reboot runs once at daemon start and has no five-field equivalent.

Gotchas

Day-of-month OR day-of-week. This is the one that bites everyone. 0 9 13 * 5 does not mean “Friday the 13th”; it means every 13th and every Friday. POSIX defines this OR behavior whenever both fields are restricted. To get an AND, restrict only one field in cron and test the other in the command: 0 9 13 * * [ "$(date +\%u)" = 5 ] && run.sh.

Escape percent signs in crontab. In a Vixie crontab a literal % is converted to a newline and the rest is fed to the command’s stdin. Write \% in date +\%Y-\%m-\%d.

Minimum interval is one minute. Standard cron cannot run every 30 seconds. Use a seconds-aware scheduler (Quartz, node-cron with six fields) or a loop inside the job.

Steps on ranges start at the range start. 10-59/15 runs at :10, :25, :40, :55, not at :15 and :30.

Daylight-saving time. When clocks jump forward, a job at 02:30 local time may be skipped; when they fall back it may run twice. Scheduling in UTC avoids both.

Hosted schedulers round or throttle. GitHub Actions runs scheduled workflows in UTC, often several minutes late at busy times, and will not run more often than every 5 minutes. Cloudflare and Vercel cron triggers also use UTC. Always check the platform docs before assuming 0 9 * * * means a 9am local run.

FAQ

What do the five fields mean?

In order they are minute (0-59), hour (0-23), day of month (1-31), month (1-12) and day of week (0-7, where both 0 and 7 are Sunday). An asterisk means every allowed value.

What does */15 mean?

A step. */15 in the minute field means every 15 minutes starting at 0, so :00, :15, :30 and :45. Steps can also start from an offset, for example 5/15 runs at :05, :20, :35 and :50.

Does the tool show the next run times?

No. It translates the expression into an English sentence so you can verify the intent. Next-run calculation depends on the host timezone and daylight-saving rules, which the browser cannot know for your server.

Can I use a seconds field or names like MON and JAN?

Yes. The explainer accepts a leading seconds field (6 fields) as used by Quartz, Spring and many Node schedulers, and three-letter names for months and weekdays. Special characters L, W and # from Quartz are also understood.

Why does my job run on more days than expected?

When both day-of-month and day-of-week are restricted, most cron daemons run the job when EITHER matches, not both. 0 9 1 * 1 fires on the first of every month and on every Monday. There is no standard way to express 'first Monday' in plain crontab; use a shell test or a scheduler that supports the # syntax.

What timezone does cron use?

The timezone of the machine or service running the daemon, which is often UTC on servers and containers. A job scheduled for 0 9 * * * on a UTC host runs at 9:00 UTC, not 9:00 your local time. Some schedulers (GitHub Actions, Vercel, Kubernetes CronJob with timeZone) let you override it.