1. What this tool does
This page takes a single cron expression, parses it, and shows two things side by side: a plain-English description of what the schedule means, and the next five times the schedule will fire from your browser’s wall clock. It accepts the standard five-field POSIX cron grammar — minute, hour, day-of-month, month, day-of-week — plus the named aliases @yearly, @annually, @monthly, @weekly, @daily, @midnight, and @hourly. Everything happens in the page — there is no fetch, no XHR, no analytics. The tool deliberately stops at the standard subset: no 6- or 7-field cron with leading seconds and trailing year, no Quartz extensions (L, W, #, ?), no custom start-time picker, no shareable URL.
2. What a cron expression is
A standard cron expression is five whitespace-separated fields that together describe a recurring schedule. Reading left to right, the fields are minute, hour, day-of-month, month, and day-of-week. Each field carries a small alphabet of glyphs: * as a wildcard that matches every value in the field’s range, , to list explicit values, - to express a contiguous range, and / to step through a range at a fixed interval. A scheduler iterates forward in time and fires the job whenever every field matches the current moment. The valid ranges per field are minute 0–59, hour 0–23, day-of-month 1–31, month 1–12, and day-of-week 0–7 where both 0 and 7 are Sunday. One footgun: when both day-of-month and day-of-week are constrained, classic Vixie cron treats the relationship as an OR — so 0 0 1 * 1 fires on the first of the month or on Mondays, not on the first and a Monday[2].
3. A brief history
Cron first shipped with Unix V7 from Bell Labs in 1979. Brian Kernighan wrote the original cron(8) as a small daemon that re-read its schedule once a minute and dispatched jobs whose time had come. The design was deliberately tiny — a process per machine, a single shared schedule, no backfill — and it set the shape every later scheduler had to relate to. The version of cron most modern Linux systems actually run descends from Paul Vixie’s rewrite in the late 1980s, which introduced per-user crontabs, the /etc/crontab format with explicit usernames, the named aliases, and the three-letter month and day-of-week tokens.
Vixie cron’s behaviour eventually became the de facto standard, and the parts that overlap with POSIX were formalised in the IEEE 1003.1 crontab specification[1]. In parallel, the Java scheduling library Quartz emerged in the early 2000s with its own dialect — a six- or seven-field expression that added seconds at the front, year at the back, and new glyphs (L for last, W for nearest weekday, # for Nth weekday of month, ? as a placeholder between the two day fields). Cron then quietly re-conquered the cloud era: Kubernetes CronJob, GitHub Actions schedule, Amazon EventBridge, and Google Cloud Scheduler all picked the POSIX five-field flavour as their interface, leaving Quartz syntax inside its Java-scheduler home.
4. Field-by-field reference
Each of the five positional fields takes values from a fixed range and optionally one of the supported aliases. The table below summarises the standard subset this tool accepts.
- Minute —
0–59. Examples:*/15(every 15 minutes starting at minute 0),0,30(on the hour and half-hour). - Hour —
0–23. Examples:9-17(each business hour),*/6(every six hours starting at midnight). - Day-of-month —
1–31. Combined with month, this is where impossible dates such as February 31 produce schedules that never fire. - Month —
1–12or three-letter aliasesJAN–DEC(case-insensitive). - Day-of-week —
0–7where both0and7mean Sunday, or three-letter aliasesSUN–SAT(case-insensitive).
5. The glyphs in depth
The four glyphs do most of the expressive work. The wildcard * matches every legal value in a field’s range, so a field of pure * imposes no constraint. The list operator , expresses a discrete set, as in 0,15,30,45. The range operator - expresses a contiguous span: 9-17 for nine through seventeen inclusive. The step operator / walks a range at a fixed stride; */5 in the minute field is shorthand for “every 5 minutes starting from minute 0”, equivalent to 0,5,10,15,20,25,30,35,40,45,50,55. Step always anchors at the first value of the underlying range, which is why */5 in a 0-based field starts at 0 but in a 1-based field starts at 1 — a subtle source of surprise when you copy a step expression from minutes (0–59) over into days-of-month (1–31).
6. Named aliases
Vixie cron added a short list of named aliases as readable stand-ins for whole-field expressions. The supported set is @yearly and @annually (0 0 1 1 *), @monthly (0 0 1 * *), @weekly (0 0 * * 0), @daily and @midnight (0 0 * * *), and @hourly (0 * * * *). The aliases are pure sugar — pick whichever form reads more clearly in your config file.
7. The Quartz extensions and why we don’t support them
The Quartz dialect adds four glyphs: L for the last day of a month or week, W for the nearest weekday to a given date, # to pick the Nth weekday of a month, and ? as a placeholder used in either of the two day fields when the other is constrained. These are useful inside Quartz, Jenkins build triggers, and a few related stacks, but the cloud-native schedulers most engineers reach for today — Kubernetes, GitHub Actions, EventBridge, Cloud Scheduler — all reject them. This tool intentionally returns a friendly error if you paste an expression containing any of them, so you do not ship something that fails in the production scheduler you actually use. If you are inside a Quartz environment, your scheduler likely has a dedicated explainer built in.
8. Common use cases and anti-patterns
The expressions that come up most often are also the most tactical. */5 * * * * fires every five minutes — typical for short-poll workers, queue drains, or external-system reconciliation jobs. 0 9 * * 1-5 fires at 9am Monday through Friday — the canonical “send the team a morning report” cadence. @daily or 0 0 * * * runs once at midnight — fine for digest emails, weak for jobs that compete for a shared resource because every cron job on every box will pile up on the same minute. 0 0 1 * * fires on the first of every month, which is what most billing-cycle and end-of-period jobs want.
The anti-patterns are easier to learn the hard way. * * * * * fires every minute — almost always too aggressive for production and usually a sign that what you wanted was a long-running worker, not a cron job. */30 * * * * is sometimes written when the author meant “on the half hour” — that interpretation happens to be correct because the minute range starts at 0, but the syntax is unintuitive enough that a future maintainer should not have to verify it twice. The day-of-month / day-of-week OR-trap mentioned earlier is the classic third footgun: never assume both day fields are AND-ed unless your scheduler explicitly documents it (some modern ones do; Vixie cron does not).
9. How to choose between cron and other schedulers
Cron is the right tool when the work is recurring, the runs are independent of each other, the job is idempotent, and the scheduler does not need to reason about retries, dependencies, or per-run state. Once the work involves a DAG of tasks, a workflow that should resume from where it failed, or a queue of jobs that need to backfill on outage recovery, reach for a workflow engine instead — Airflow, Temporal, Dagster, Prefect, or Step Functions, depending on the stack. For one-off asynchronous triggers — “run this when an upload lands in the bucket” — an event bus or message queue is a better fit than a per-minute poll. The natural cloud pairings are Kubernetes CronJob for in-cluster recurring work, GitHub Actions schedule for repo automation that runs as part of CI, and EventBridge or Cloud Scheduler for cross-service triggers — and all three speak the same POSIX five-field cron this page describes.
10. References
- IEEE and The Open Group. POSIX.1-2017,
crontab(Open Group Base Specifications, Issue 7). https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html — the canonical specification of the five-field cron expression format, including the valid range of each field, the meaning of the glyphs*,,,-, and/, and the day-of-month / day-of-week OR-rule that the cloud-native schedulers ultimately reference. - Vixie cron upstream
crontab(5)manual page. https://man.archlinux.org/man/crontab.5 — the de facto behaviour of cron in modern Linux distributions, including the named aliases (@hourly,@daily, and the rest), the three-letter month and day-of-week aliases (JAN–DEC,SUN–SAT), and the practical interpretation of step values and the day-of-month / day-of-week OR-rule that the parsing library this page uses follows.
Related tools
- Regex Tester →
The other small alphabet engineers tune scheduled jobs against — log filtering, path matching, output validation. Same audience.
- JWT Decoder →
Cron jobs that hit authenticated APIs usually carry a bearer token; the natural next stop when a job-side request is rejected.
- UUID Generator →
Generate correlation IDs for scheduled-job runs — pairs with cron when wiring up tracing for batch workloads.
- Base64 / URL / HTML Encoder–Decoder →
Encode/decode the secrets and payloads that scheduled jobs pass through CI env vars or job arguments.