DevToolNow

Cron Expression Cheatsheet: Every Field Explained

DevToolNow Editorial Team···10 min read

Cron expressions look simple — five fields and a few special characters — and the syntax has been stable for decades. The reason engineers still get them wrong is that there is no single cron. POSIX specifies one dialect, Vixie cron extends it, Quartz changes the field count, AWS EventBridge bends both, and DST rules differ between implementations. This cheat sheet covers what is portable, what is not, and where the production-grade traps are.

1. The five-field standard

POSIX cron, Vixie cron, cronie, and the cron in most Linux distributions all take a five-field expression. Left to right:

* * * * *
| | | | |
| | | | +-- day of week (0–6 or SUN–SAT; 0 and 7 are both Sunday)
| | | +---- month (1–12 or JAN–DEC)
| | +------ day of month (1–31)
| +-------- hour (0–23)
+---------- minute (0–59)

Field ranges are inclusive on both ends. Names are case-insensitive but only three-letter abbreviations are accepted; JANUARY will not parse. When both day-of-month and day-of-week are restricted, standard Vixie cron treats them as a logical OR — 0 0 1 * MON fires on the 1st of every month and on every Monday, not just on Mondays that fall on the 1st.

2. Special characters

All five fields accept the same set of operators, with subtle dialect differences:

  • * — every value in the field's range.
  • , — list. 0,15,30,45 * * * * fires four times per hour.
  • - — range. 0 9-17 * * MON-FRI fires hourly during business hours on weekdays.
  • / — step. */15 * * * * fires every 15 minutes; 0 */2 * * * fires on every even hour.
  • ? — "no specific value". Quartz only. Required to disambiguate day-of-month vs day-of-week.
  • L, W, # — last/weekday/nth-of-month modifiers. Quartz only; Vixie cron does not understand them.

3. Nicknames: @hourly, @daily, @reboot

Vixie cron and cronie accept a small set of macros that expand to fixed expressions:

NicknameExpansionMeaning
@yearly / @annually0 0 1 1 *Once a year, midnight Jan 1
@monthly0 0 1 * *Midnight on the 1st
@weekly0 0 * * 0Midnight Sunday
@daily / @midnight0 0 * * *Every midnight
@hourly0 * * * *Top of every hour
@rebootOnce at cron startup

Busybox cron, used in many Alpine-based container images, supports only a subset of these. Confirm before relying on them in a Dockerfile.

4. Patterns you actually use

  • */15 * * * * — every 15 minutes
  • 0 */2 * * * — every two hours on the hour
  • 0 9 * * 1-5 — weekdays at 09:00
  • 0 0 1 * * — first day of every month at midnight
  • 0 22 * * 0 — Sunday at 22:00
  • 30 3 * * * — every day at 03:30 (a common low-traffic batch slot)
  • 0 0 1 1 * — once a year, January 1st
  • 0 0 * * 1#1 — first Monday of every month (Quartz only)

5. Quartz and AWS EventBridge: the 6-field cron

Quartz Scheduler — the cron engine inside Spring's @Scheduled, ServiceNow, and many Java systems — uses a 6- or 7-field expression. The order is seconds minutes hours day-of-month month day-of-week [year]. AWS EventBridge cron expressions are similar in shape but require a 6th field and use ? instead of * in one of the day fields. EventBridge also explicitly does not support 0 as Sunday — it uses 1-7 for SUN–SAT.

# Quartz: every day at 09:00:00
0 0 9 ? * *

# AWS EventBridge: every weekday at 18:00 UTC
cron(0 18 ? * MON-FRI *)

6. DST, timezones, and the "ran twice" bug

Cron interprets expressions in the system's local timezone unless told otherwise. When clocks spring forward, expressions targeting the skipped hour silently do not run that day. When clocks fall back, expressions targeting the repeated hour can run twice. Vixie cron 4.x added partial DST handling that tries to do the right thing, but the behavior varies and it is not portable.

Two reliable fixes: set the host's timezone to UTC and write all cron expressions in UTC, or use a scheduler that takes an explicit timezone (systemd timers, GitHub Actions workflows, cloud schedulers). The IANA TZ Database is the canonical source for zone names, and it is already on every Linux distribution.

7. systemd timers and other alternatives

On a modern Linux host, systemd timers are usually the better choice. They support sub-second precision, named timezones via OnCalendar=, persistent catch-up after missed windows (Persistent=true), randomised delay to spread load (RandomizedDelaySec=), and dependency on other units. Logs land in journald automatically, which is a sharp improvement over the "you have to redirect stderr or the email goes to root" default of cron.

anacron exists for laptops and other systems that are not on 24/7 — it runs missed jobs at the next opportunity rather than skipping them. fcron blends cron and anacron. For container workloads, the right answer is usually a Kubernetes CronJob or a managed scheduler (EventBridge, Cloud Scheduler) rather than a cron daemon inside the container.

Build cron expressions visually

DevToolNow's Cron Generator builds expressions field by field, shows the next 10 fire times, and produces both 5-field Vixie and 6-field Quartz output for copy-paste into your scheduler.

Open Cron Generator →

Frequently asked questions

Q. Is cron 5 fields or 6 fields?

A. Standard Unix cron — Vixie cron, cronie, busybox cron — is 5 fields: minute, hour, day-of-month, month, day-of-week. Quartz (the Java scheduling library used by Spring, Quartz Scheduler, AWS EventBridge classic) and most cloud schedulers use 6 fields, prepending a seconds field. AWS EventBridge cron expressions add a 7th field (year). Always confirm which dialect your runner accepts before copy-pasting an expression.

Q. What is the difference between * and ? in the day fields?

A. In Quartz cron, day-of-month and day-of-week cannot both be * — you must put ? in one of them to mean "don't care". Standard Unix cron does not use ? at all and treats * in both day fields as an OR. This is the single most common source of cross-dialect bugs.

Q. What does @reboot do, and is it reliable?

A. @reboot in Vixie cron and cronie runs the job once each time cron itself starts (typically at boot). It is convenient but coarse: it does not wait for network or other services to be ready, and busybox cron does not support it at all. For service-style startup tasks, prefer a systemd unit with proper After= and Wants= dependencies; reserve @reboot for trivial init like clearing a temp directory.

Q. How does cron behave during daylight saving time?

A. Most cron implementations interpret expressions in the system's local time. When clocks spring forward, jobs scheduled in the skipped hour do not run that day. When clocks fall back, jobs scheduled in the repeated hour can run twice unless cron has explicit DST handling. The portable fix is to set the system timezone to UTC for any servers running cron, or use a scheduler that takes a timezone parameter.

Q. When should I use systemd timers instead of cron?

A. Use systemd timers when you need: precise calendar specifications including seconds and timezones, dependency on other units, journald log collection, persistent timers that catch up after a missed window, or randomised delay to spread load. Use cron when the host has no systemd or when shipping a portable script that must work on Alpine, BSD, or busybox-based images.

References

  • POSIX.1-2017 — crontab utility specification (IEEE Std 1003.1)
  • man 5 crontab (Vixie cron / cronie)
  • man 5 systemd.timer and systemd.time
  • AWS EventBridge — Schedule Expressions for Rules
  • crontab.guru — interactive expression explainer

Note: Cron dialects diverge in subtle ways. Always validate an expression against the specific scheduler you target (Vixie cron, Quartz, EventBridge, Kubernetes CronJob) before relying on it for production traffic.

About the DevToolNow Editorial Team

DevToolNow's editorial team is made up of working software developers who use these tools every day. Every guide is reviewed against primary sources — IETF RFCs, W3C/WHATWG specifications, MDN Web Docs, and project repositories on GitHub — before publication. We update articles when standards change so the guidance stays current.

Sources we cite: IETF RFCs · MDN Web Docs · WHATWG · ECMAScript spec · Official project READMEs on GitHub