What is a cron expression?

A cron expression is a compact, five-to-seven-field string that tells a scheduler when to run a job. The classic POSIX form has five fields, minute, hour, day-of-month, month, day-of-week, separated by spaces. 0 9 1-5 means "9:00 AM, Monday through Friday". Quartz-style cron adds a leading seconds field; some implementations append a trailing year field for long-range scheduling.

Cron expressions are everywhere: crontab, systemd timers, Kubernetes CronJobs, GitHub Actions schedules, AWS EventBridge rules, Vercel cron, Cloudflare Workers cron triggers, n8n schedule nodes, Airflow DAGs. The syntax is the same in all of them, but the small dialect differences (5 vs 6 vs 7 fields, ? placeholders, L last-day, # nth-weekday) trip people up constantly.

How to use this tool

1. Paste your cron expression into the input. Five-field POSIX is the default; the parser auto-detects 6-field (with seconds) and 7-field (with year) forms. 2. Read the plain-English explanation below the input, it spells out exactly which minutes, hours, days, and weekdays the expression matches. 3. Check the field-by-field validation panel, each field shows ✓ if it parses or a specific error if it doesn't (e.g. "Hour: 24 is out of range, must be 0–23"). 4. Inspect the next six firings in the preview list. Toggle between UTC and your local timezone to confirm what your scheduler actually sees vs what your team will experience. 5. Click a preset in the patterns card to load common expressions (every minute, hourly, daily at midnight, weekdays at 9 AM, monthly, etc.), useful as a starting point or a sanity check. 6. Download an .ics calendar file of the next firings, paste it into Google Calendar, Outlook, or Apple Calendar to visualise the schedule alongside the rest of your week.

Cron field reference

Field Range Notes
Seconds 0–59 Quartz only (6/7-field).
Minute 0–59
Hour 0–23 24-hour clock.
Day of month 1–31 `?` allowed in Quartz when DOW is set.
Month 1–12 or `jan`–`dec` Aliases case-insensitive.
Day of week 0–6 or `sun`–`sat` 0 = Sunday in POSIX.
Year 1970–2099 7-field only.

Each field accepts: a single value (5), a list (1,3,5), a range (1-5), a step over a range (/15 = every 15, 0-30/5 = 0,5,10,…,30), or any combination joined with commas (0-30/5,45). The wildcard means "every value in the field's range".

Common patterns, decoded

  • *, every minute, forever. Almost never what you want in production.
  • /15 *, every 15 minutes (:00, :15, :30, :45).
  • 0 , top of every hour.
  • 0 9 1-5, 9:00 AM, Monday through Friday.
  • 0 0 0, midnight every Sunday.
  • 0 0 1 , midnight on the 1st of each month.
  • 0 0 1 1 *, New Year's Day at midnight.
  • 30 2 1, 2:30 AM every Monday (a classic backup window).

Common gotchas

  • Day-of-month vs day-of-week is OR, not AND. 0 0 1 * 1 fires at midnight on either the 1st of any month or any Monday, not just Mondays that fall on the 1st. To restrict to "first Monday of the month" you need cron extensions (#) or a wrapper script that checks the date.
  • Sunday is 0 in POSIX, 1 in Quartz. Off-by-one weekday bugs are the single most common cron mistake. If you copy a Quartz expression into a POSIX scheduler (or vice versa), Sunday-vs-Monday will silently shift by one.
  • Timezone matters. Most schedulers run cron in UTC unless you explicitly set a timezone. 0 9 * is 9:00 AM UTC, which is 4:00 AM Eastern in winter and 5:00 AM in summer. The "Local" toggle in this tool shows you what the firings will look like in your browser's timezone.
  • */7 doesn't mean "every 7 days".* Step expressions reset at the start of each higher-level period. /7 in the day-of-month field fires on the 1st, 8th, 15th, 22nd, 29th, and then again on the 1st of the next month, breaking the 7-day cadence.
  • Seconds field is silently ignored by POSIX cron. If your scheduler is plain crontab and you paste in a 6-field Quartz expression, the first field is interpreted as minutes, your job runs an order of magnitude more often than you intended.

Privacy

Your cron expressions and the firing previews are computed entirely in your browser. Nothing is uploaded. Recent expressions are stored only in your browser's localStorage and you can clear them from the Recent card. The .ics export is generated locally and downloaded directly from your machine.

Frequently asked

Is my cron expression sent to a server?

No. Parsing, validation, plain-English explanation, next-firing computation, and .ics export all run in your browser. Nothing is uploaded. Recent expressions are stored only in localStorage and you can remove them from the Recent card.

Which cron dialects does this tool support?

Five-field POSIX cron (the standard 'crontab' format), six-field Quartz cron with a leading seconds field, and seven-field cron with a trailing year field. The parser auto-detects which dialect you've pasted by counting fields.

Why is Sunday 0 here when my scheduler uses 1?

POSIX cron uses 0 for Sunday; Quartz uses 1. This tool follows POSIX in the day-of-week field (0–6, where 0=Sun), and accepts the 'sun, mon, tue…' aliases for clarity. If your target scheduler is Quartz-based (like Spring's @Scheduled or Apache Airflow's older versions), shift the day-of-week numbers by one.

Is the next-firings preview in UTC or my local time?

Both. The toggle above the preview switches between UTC (what your scheduler sees) and your browser's local timezone (what your team experiences). The two often differ by hours — confirming both is a good habit before you commit a cron change.

What does 'day-of-month and day-of-week are OR' actually mean?

If you set both DOM and DOW to non-wildcard values, classic POSIX cron fires when EITHER condition matches, not both. So '0 0 1 * 1' fires at midnight on the 1st of every month AND on every Monday — not just Mondays that fall on the 1st. To restrict to specific weekday-of-month, you need Quartz extensions like '#' or a wrapper.

Why doesn't '*/7' fire every 7 days?

Step expressions reset at the start of each parent period. '*/7' in the day-of-month field fires on days 1, 8, 15, 22, 29 — then resets on the 1st of the next month, breaking the 7-day cadence. For a true 'every N days' schedule, use a scheduler that supports interval triggers, not cron.

Can I export the schedule to my calendar?

Yes. Click 'Download .ics' to grab an iCalendar file containing the next several firings. Import it into Google Calendar, Outlook, Apple Calendar, or any other client that speaks ICS. Useful for confirming a backup window doesn't collide with a meeting.

What does 'every 15 minutes between 9 AM and 5 PM, weekdays only' look like?

0,15,30,45 9-17 * * 1-5 — minutes 0/15/30/45, hours 9 through 17 inclusive, any day of month, any month, weekdays Monday through Friday. The same can be written more compactly as '*/15 9-17 * * 1-5'.