Uttir
By Uttir 6 min read

What Is a Cron Expression? A Beginner's Guide With Examples

A cron expression is a 5-field syntax for scheduling recurring tasks. Learn what each field means, the special characters (*, /, -, ,), common patterns (every minute, every hour, weekdays at 9am), and how to build one without memorising the syntax.

A cron expression is a 5-field string that defines when a recurring task should run. The five fields, in order: minute (0-59), hour (0-23), day of month (1-31), month (1-12), day of week (0-6, where 0 is Sunday). The syntax supports * (any), / (every), - (range), and , (list). The <a href="/cron-parser">Uttir Cron Parser</a> explains any cron expression in plain English; the <a href="/cron-generator">Cron Generator</a> builds one from a description; the <a href="/time-zone-converter">Time Zone Converter</a> is the right tool if your cron runs in a different timezone than you do.

You have a task that should run every Monday at 9am. Or every 5 minutes. Or on the first of every month. The cron expression is the syntax for saying so, and it is the syntax you have to learn if you are doing any kind of scheduled work in Unix, Linux, cloud services, or CI pipelines.

This post is the beginner's guide. What each field means, what the special characters do, the common patterns, and how to build one without memorising the syntax. The Uttir Cron Parser takes any cron expression and explains it in plain English; the Cron Generator builds an expression from a description. The Time Zone Converter is the right tool when your cron runs in a different timezone than you do.

The 5-field structure

A standard cron expression has 5 fields, separated by spaces:

* * * * *
│ │ │ │ │
│ │ │ │ └── day of week (0-6, Sunday=0)
│ │ │ └──── month (1-12)
│ │ └────── day of month (1-31)
│ └──────── hour (0-23)
└────────── minute (0-59)

That is the whole structure. Five fields, in this order, each with a specific range. The cron daemon (or the scheduler, or the cloud service) reads the expression and runs the task at every minute that matches all five fields.

Some systems (newer cron implementations, some cloud schedulers) add a 6th field for seconds at the front, making it S M H D M W. The 5-field version is the standard for cron on Unix and Linux; the 6-field version is common in Java-based schedulers (Quartz) and in cloud services like AWS CloudWatch Events. The Cron Parser handles both.

The special characters

Four special characters make the syntax expressive. They combine to define most of the schedules you will ever need.

* (asterisk). Means "any" or "every." In the minute field, * means "every minute." In the hour field, it means "every hour." In the day-of-month field, it means "every day." A cron expression of * * * * * runs every minute, of every hour, of every day, of every month, of every day of the week. Which is to say, every minute.

/ (slash). Means "every N." In the minute field, */5 means "every 5 minutes" (0, 5, 10, 15, ...). In the hour field, */2 means "every 2 hours" (0, 2, 4, ...). The slash combines a starting point and a step. The Cron Generator builds these for you.

- (hyphen). Means "range." In the hour field, 9-17 means "hours 9 through 17, inclusive." In the day-of-week field, 1-5 means "Monday through Friday." The hyphen defines a contiguous range.

, (comma). Means "list." In the minute field, 0,15,30,45 means "minutes 0, 15, 30, and 45." In the day-of-week field, 1,3,5 means "Monday, Wednesday, and Friday." The comma defines a discrete set.

The four characters combine. 0 9-17 * * 1-5 means "minute 0, hours 9 through 17, every day, every month, weekdays only" — every hour on the hour, from 9am to 5pm, Monday through Friday. The Cron Parser decodes this kind of expression for you.

The common patterns

About a dozen patterns cover 90% of the cron expressions you will ever write. Memorise these and you can schedule almost anything.

Every minute. * * * * *

Every 5 minutes. */5 * * * *

Every 15 minutes. */15 * * * *

Every 30 minutes. */30 * * * *

Every hour, on the hour. 0 * * * *

Every day at midnight. 0 0 * * *

Every day at 9am. 0 9 * * *

Every day at 5:30pm. 30 17 * * *

Every Monday at 9am. 0 9 * * 1

Every weekday at 9am. 0 9 * * 1-5

First of every month at midnight. 0 0 1 * *

Every Sunday at 3am. 0 3 * * 0

Every 15 minutes between 9am and 5pm, weekdays only. */15 9-17 * * 1-5

These are the ones you will copy-paste most often. The Cron Generator builds them, the Cron Parser decodes them.

Things to watch out for

Cron expressions look simple, and they are, but there are a few things that bite people in practice.

Day-of-month AND day-of-week. When both day-of-month and day-of-week are non-*, the cron runs when EITHER matches. Most people expect AND (when both match), but the syntax is OR. 0 9 1 * 1 means "9am on the 1st of the month OR 9am on Monday" — both. To get "9am on the 1st of the month AND only if it's a Monday," you have to write the day-of-week filter into a wrapper script.

Timezone. Cron runs in the system timezone of the server. If your server is in UTC and you write 0 9 * * * expecting 9am Eastern, the cron will run at 4am Eastern. The fix is either to set the server's timezone to the one you want, or to convert the cron to UTC. The Time Zone Converter is the right tool for the conversion.

Daylight saving time. If your server is in a timezone that observes DST and the cron runs at 2am, the cron might not run on the spring-forward day (because 2am does not exist that day) or might run twice on the fall-back day (because 2am happens twice). The fix is either to use UTC (no DST) or to schedule the cron at a time that is safely outside the DST transition (most production systems use 3am or 4am, well after the transition).

Overlapping schedules. If you have two cron expressions that could run at the same time, they will. The cron daemon does not deduplicate; it runs the task at every matching minute, even if the task is already running from a previous match. The fix is to make the task itself idempotent (safe to run multiple times) or to add a lockfile / database lock to prevent concurrent runs.

The 5-field vs 6-field confusion. Quartz (and AWS CloudWatch Events) use a 6-field expression with seconds at the front. 0 0 12 * * ? in Quartz is "12:00:00pm every day" (the ? is a placeholder for "no specific value" in the day-of-week field). The 5-field version of the same schedule is 0 12 * * *. The Cron Parser handles both, but make sure you are writing the version your scheduler expects.

How to use cron in the cloud

Cron is not just for Linux. Every cloud service has a scheduler that accepts cron expressions or something close to them.

AWS CloudWatch Events / EventBridge. Uses a 6-field cron syntax. The schedule rules accept the expression in the same format as Quartz.

Google Cloud Scheduler. Uses the standard 5-field cron syntax. Specify a timezone in the job definition to avoid the UTC gotcha.

Azure Logic Apps / Functions. Uses an NCRONTAB expression (also 6-field, with seconds at the front) for the timer trigger.

GitHub Actions. Uses POSIX cron syntax (5-field) for the schedule trigger. The on.schedule field accepts a cron expression and runs the workflow on the matching schedule.

Vercel Cron Jobs. Uses the standard 5-field cron syntax. The schedule is defined in the vercel.json file.

All of these accept the same basic cron syntax. The differences are the surrounding config (timezone, retry policy, dead-letter queue) and whether the expression is 5-field or 6-field. The Cron Parser works for any of them.

How to do it in the browser

The Uttir Cron Parser takes any cron expression and explains it in plain English. Paste */15 9-17 * * 1-5, see "Every 15 minutes, between 09:00 and 17:59, Monday through Friday." The Cron Generator goes the other way: pick from common patterns or build a custom one, see the expression. The Unix Timestamp Converter is the right tool if you want to know exactly when the next run will happen. The Date Calculator and Date Add/Subtract are the right tools if you are doing the date math around a schedule.

For the time-zone-related gotcha, the Time Zone Converter is the right tool to convert a cron schedule from your local timezone to UTC (or vice versa) before you paste it into a scheduler.

#cron#scheduling#developer-tools#devops#best-practices

New tools and guides, once a week

One short email when something new ships. No tracking, no images, unsubscribe with one click.