Skip to content
PithLab

↑↓ to move · Enter to open · Esc to close

Cron expressions explained with 12 examples

· 3 min read

Cron is how Unix systems run jobs on a schedule, and its five-field syntax has spread to CI pipelines, cloud schedulers and job queues. It's compact, but it's easy to write a schedule that runs at a time you didn't mean. Here's how to read one confidently.

The five fields

┌──────── minute (0–59)
│ ┌────── hour (0–23)
│ │ ┌──── day of month (1–31)
│ │ │ ┌── month (1–12)
│ │ │ │ ┌ day of week (0–6, Sunday = 0; 7 is also Sunday in most crons)
│ │ │ │ │
* * * * *

Each field takes:

  • *: every value.
  • A number: exactly that value.
  • a,b,c: a list.
  • a-b: a range.
  • */n or a-b/n: every nth value.

Months and weekdays can usually be written as names too: JAN, MON.

12 examples

Expression Runs
* * * * * Every minute
*/5 * * * * Every 5 minutes (at :00, :05, :10…)
0 * * * * At the start of every hour
30 2 * * * Every day at 02:30
0 9 * * 1-5 09:00 Monday to Friday
0 9,17 * * 1-5 09:00 and 17:00 on weekdays
0 0 1 * * Midnight on the 1st of every month
0 0 * * 0 Midnight every Sunday
15 14 1 * * 14:15 on the 1st of every month
0 */6 * * * Every 6 hours (00:00, 06:00, 12:00, 18:00)
0 8 1 1,4,7,10 * 08:00 on the first day of each quarter
0 22 * * 1-5 22:00 on weekdays

Paste any of these into the cron expression parser to get a plain-English description and the next run times.

Trap 1: day of month OR day of week

When both the day-of-month and day-of-week fields are restricted, classic cron runs the job when either matches, not both. So:

0 9 13 * 5

doesn't mean "Friday the 13th". It means "the 13th of every month, and also every Friday". If you need both conditions, schedule the job for one of them and check the other inside the script.

Trap 2: */n restarts every hour or day

*/45 * * * * runs at :00 and :45, then :00 again 15 minutes later, because the step counts from the start of each hour. Cron can't express "every 45 minutes" evenly across hours. Pick a step that divides 60 (or 24 for hours), or run every 15 minutes and let the job decide.

Trap 3: time zones

Cron uses the time zone of the machine or service running it. Many servers and cloud schedulers run in UTC. A job at 0 9 * * * on a UTC server runs at 09:00 UTC, which is 10:00 in London during British Summer Time and 05:00 in New York during daylight saving time.

Daylight saving also creates odd days. In zones that change the clocks, a 02:30 job may be skipped on the night clocks go forward and run twice when they go back. Schedule important jobs outside the 01:00–03:00 window, or run the scheduler in UTC. The time zone converter helps you check what a UTC time means for the people who care about the result.

Trap 4: six fields or five?

Some schedulers add a seconds field at the start, and some add a year at the end. Quartz-style expressions also use ? in one of the day fields. If an expression has six or seven parts, check which dialect the tool expects before copying it.

Writing a schedule you can trust

  1. Write it in words first: "weekdays at 09:00 UK time".
  2. Decide the time zone the scheduler runs in and convert.
  3. Write the expression and check its next runs in a parser.
  4. Add a comment next to it in your config saying what it means. Future you will thank you.

Tools in this post

Keep reading

  • Unix timestamps and time zones, explained

    Why 1700000000 is a date, why your timestamp is 1,000 times too big, and how to store and show times without time zone bugs. A practical guide with examples.

  • JSON vs YAML: when to use which

    JSON and YAML describe the same data, but they fail in different ways. A practical guide to choosing between them, with the YAML gotchas that bite in production.

  • How to read a JWT without leaking it

    A JSON Web Token is just three Base64url chunks. Here's how to read the header and claims, what to check, and why you should never paste one into a random site.