Cron Expression Explainer
Paste a cron expression to see what it means in plain English, a field-by-field breakdown, and the next times it will run. Standard 5-field and 6-field (with seconds) syntax, @daily-style aliases and month/day names are all supported.
| Field | Name | Meaning |
|---|
Next runs (your local time)
Related tools
A cron expression is a compact schedule: five fields (minute, hour, day-of-month, month, day-of-week) that together say "run at these times". The syntax is terse and easy to misread, which is how a job meant for 3 AM ends up running every minute.
The five fields
In order: minute (0–59), hour (0–23), day-of-month (1–31), month (1–12 or JAN–DEC), day-of-week (0–6 or SUN–SAT, where both 0 and 7 mean Sunday). Some schedulers (Quartz, Spring and a few other libraries) add a leading seconds field, making six; this tool detects that automatically. The @yearly, @monthly, @weekly, @daily and @hourly aliases are shorthand for common five-field expressions.
Stars, ranges, lists and steps
*— every value of the field.5— exactly that value.1-5— an inclusive range (Monday to Friday, if it's the day-of-week field).1,15,30— a list of specific values.*/15— a step: every 15th value starting from the minimum (so minutes 0, 15, 30, 45).9-17/2— a step within a range (9, 11, 13, 15, 17).
Common gotchas
The one that catches people most often: if you restrict both day-of-month and day-of-week (neither is *), cron runs the job when either matches, not both. So 0 0 13 * 5 runs on the 13th of every month and every Friday. Also: */5 in the hour field means "every 5 hours from midnight" (0, 5, 10, 15, 20), not "every 5 minutes"; and a bare number in the day-of-week field is 0=Sunday, so 1 is Monday, not the first day.
Cron syntax beyond crontab
The five-field format outlives the original cron daemon it came from. GitHub Actions' schedule: trigger takes the exact same syntax, evaluated in UTC by default regardless of the repository's own settings. Kubernetes' CronJob resource uses it too, running on the cluster's own clock unless you set a time zone. Many other CI and scheduling platforms — GitLab CI, CircleCI, various cloud schedulers — copied the same five fields specifically because so many people already know it. Learning it once here carries over directly to all of them.
On a Linux server itself, cron jobs can live in a few different places: a user's personal crontab (edited with crontab -e), system-wide files under /etc/cron.d/, or the convenience folders /etc/cron.daily/, /etc/cron.weekly/ and /etc/cron.monthly/ (which just run everything inside them once a day/week/month, no expression needed). /etc/cron.d/ entries include an extra field — which user to run the command as — that a personal crontab doesn't need, since it's already scoped to one user.
Frequently asked questions
Is my cron expression sent anywhere?
No. Parsing, the description and the next-run calculation all happen in your browser. Nothing is transmitted.
Which time zone are the "next runs" in?
Your device's local time zone, formatted in the site language. On a real server the job runs in that server's time zone, which may differ.
Does it support L, W and #?
Not yet — those Quartz extensions ("last day of month", "nearest weekday", "nth weekday") aren't part of standard crontab. Standard steps, ranges, lists, names and the ? placeholder are all handled.
Why does my job run more often than I expected?
Usually a stray * or a misplaced */n. The plain-English sentence and field table above are there to catch exactly that before you deploy it.
Can I use this syntax in GitHub Actions or Kubernetes?
Yes — both use the same five-field format this tool explains. GitHub Actions evaluates schedules in UTC by default, not in your own time zone, which is a common source of "it ran at the wrong time" surprises.
What's the difference between crontab and /etc/cron.d?
A personal crontab (edited with crontab -e) is scoped to one user and needs only the standard five fields. Files under /etc/cron.d/ are system-wide and add an extra field specifying which user account should run the command, since there's no single owner to assume.