>_
🛠 Tools & Productivity · 3 min read Tutorial

Cron Expression Cheat Sheet: Common Patterns, Time-Zone Traps and Platform Differences

What the five fields mean, a quick-reference table of common schedules, the special day-of-month / day-of-week rule, and how Linux, Kubernetes, GitHub Actions and Spring differ.

Nearly every back-end developer has written a cron expression, yet few get every detail right the first time. Here is a cheat sheet worth bookmarking, followed by the most common traps.

The five fields

A standard cron expression has five space-separated fields:

┌───────── minute (0–59)
│ ┌─────── hour (0–23)
│ │ ┌───── day of month (1–31)
│ │ │ ┌─── month (1–12 or JAN–DEC)
│ │ │ │ ┌─ day of week (0–7, both 0 and 7 are Sunday, or SUN–SAT)
│ │ │ │ │
* * * * *

Each field accepts:

SymbolMeaningExample
*any value* in the hour field means every hour
,list1,15 means the 1st and the 15th
-range9-17 means 9:00 to 17:00
/step*/15 means every 15 units

Common schedules

ExpressionMeaning
* * * * *every minute
*/5 * * * *every 5 minutes
0 * * * *every hour, on the hour
0 */2 * * *every 2 hours
0 0 * * *every day at midnight
30 8 * * *every day at 8:30
0 9 * * 1-5weekdays at 9:00
0 9,18 * * 1-5weekdays at 9:00 and 18:00
*/10 9-18 * * 1-5every 10 minutes between 9:00 and 18:59 on weekdays
0 0 * * 0every Sunday at midnight
0 3 * * 6every Saturday at 3:00
0 0 1 * *the 1st of every month at midnight
0 0 1,15 * *the 1st and 15th of every month
0 0 1 */3 *the first day of every quarter
0 0 1 1 *every 1 January
@dailysame as 0 0 * * *
@weeklysame as 0 0 * * 0
@monthlysame as 0 0 1 * *

Not sure you got it right? Paste it into the Cron Expression Parser for a plain-English description and the next 10 run times.

Trap 1: day of month and day of week are OR’ed

0 0 1 * 1

Many people read this as “the 1st of the month, if it’s a Monday”. In standard cron, though, when neither day field is *, the job runs if either one matches: it runs on the 1st of every month and on every Monday.

Trap 2: time zones

cron runs in the time zone of the machine (or platform) executing it:

  • Cloud servers and containers often default to UTC. If you write 0 9 * * * meaning 9:00 in New York, on a UTC machine it fires at 4:00 or 5:00 a.m. New York time, depending on daylight saving;
  • GitHub Actions schedule uses UTC by default;
  • Kubernetes CronJobs support a timeZone field, such as America/New_York.

To convert between UTC and local time, use the Timestamp Converter.

Trap 3: platform dialects

PlatformFieldsNotes
Linux crontab5Standard syntax
Kubernetes CronJob5Standard syntax; set the zone with timeZone
GitHub Actions5UTC by default; may be delayed at busy times; minimum interval 5 minutes
Spring @Scheduled6The first field is seconds
Quartz6–7Seconds plus optional year; one of the day fields must be ?; supports L, W, #

L (last day), W (nearest weekday) and # (nth weekday of the month) only exist in Quartz and some other implementations — standard crontab does not support them. “Last day of the month”, for example, can’t be expressed directly in standard cron; the usual workaround is to run daily and have the script check whether tomorrow is the 1st.

Trap 4: overlapping runs and silent failures

  • If a job can take longer than its interval, the next run starts before the previous one finishes. Add a lock (for example with flock) or configure the platform’s concurrency policy;
  • cron doesn’t notify you of failures by default. Redirect output to a log and set up alerts for important jobs.

Summary

  • Five fields: minute, hour, day of month, month, day of week;
  • When both day fields are set, they are OR’ed;
  • Check the time zone of the environment first;
  • When copying expressions between platforms, watch for seconds fields and extended syntax.

Tools used in this post