Cron Expression Builder
Build, validate and decode cron expressions. See next run times, a 7-day schedule grid, and copy-ready snippets for GitHub Actions, Kubernetes, and Vercel Cron.
Build a Cron Schedule
Next 7 days — schedule grid
| Day | 00 | 03 | 06 | 09 | 12 | 15 | 18 | 21 | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Sun 24 | ||||||||||||||||||||||||
| Mon 25 | ||||||||||||||||||||||||
| Tue 26 | ||||||||||||||||||||||||
| Wed 27 | ||||||||||||||||||||||||
| Thu 28 | ||||||||||||||||||||||||
| Fri 29 | ||||||||||||||||||||||||
| Sat 30 |
Next 6 runs (local time)
Describe in English → cron
Try phrases like "every weekday at 9am", "first day of every month", "every 15 minutes", "saturday and sunday at noon".
Copy for…
Presets
Syntax Reference
| Field | Allowed | Examples |
|---|---|---|
| Minute | 0–59 | 0, */5, 15-45 |
| Hour | 0–23 | 0, 9, */6, 8-17 |
| Day (month) | 1–31 | 1, 15, 28-31 |
| Month | 1–12 | 1, JAN, */3, 3-6 |
| Day (week) | 0–6 | 0=Sun, 1-5, MON-FRI |
* — any value*/n — every nth valuea-b — rangea,b,c — list of valuesCron syntax explained: the 5 fields
A standard Unix cron expression is five space-separated fields read left to right: minute (0–59), hour (0–23), day of the month (1–31), month (1–12 or JAN–DEC), and day of the week (0–6 where 0 is Sunday, or SUN–SAT). Each field accepts a fixed number, a comma-separated list, a range, an asterisk for "any", or a step value like */n. The expression matches a particular minute if every field matches that minute's timestamp. One important edge case: when both day-of-month and day-of-week are restricted, classic Unix cron treats them as an OR — the job fires if either field matches. This tool uses the same convention, which is also what Vixie cron, GitHub Actions and Vercel use.
Common cron patterns and what they mean
* * * * * fires every single minute — useful for tests, dangerous in production. */5 * * * * is the bread-and-butter polling schedule: every five minutes, on the dot. 0 * * * * means "at minute zero of every hour" — so 13:00, 14:00, 15:00 and so on. 0 9 * * 1-5 is a working-hours classic: 9am Monday through Friday. 0 0 1 * * runs once a month at midnight on the first. 0 0 * * 0 is a weekly Sunday-midnight digest. 0 3 * * * is the canonical "quiet hours" slot — 3am every day, when nobody is awake to argue with your maintenance window. If you ever see something like 0 0 28-31 * *, it's a workaround for "last day of the month" in standard cron, since Unix cron has no L token.
Standard cron vs Quartz vs cron with seconds
Three flavours of cron syntax dominate the wild. Standard Unix cron (5 fields, minute precision) is what crontab, GitHub Actions, Kubernetes CronJob, Vercel Cron, and most serverless schedulers use. Quartz (Java, Spring, Hangfire, AWS EventBridge in some configurations) adds a leading seconds field and a trailing year field for 6 or 7 total, and introduces extras like L (last), W (nearest weekday), and# (nth occurrence). Cron-with-seconds sits in between: 6 fields, starting with seconds — used by Cron4j and some background-job libraries. Pasting a 6-field Quartz expression into a 5-field scheduler will silently misalign every value, so always confirm which dialect your platform expects before copying.
Cron pitfalls: timezone, DST, missed runs, overlap
Cron looks deterministic, but four things bite people in production. First, timezone: most managed schedulers (GitHub Actions, Vercel Cron, AWS EventBridge defaults) interpret your expression in UTC, not your local time. A 0 9 * * 1-5 intended as "9am London" will fire at 10am London in winter and 9am London in summer if you forget to set the timezone explicitly. Second, DST: when the clock jumps forward, expressions targeting the skipped hour never fire that day; when it falls back, they may fire twice. Schedulers handle this differently, so check your platform's docs. Third, missed runs: if the host is down at the firing minute, classic cron simply skips that run — only some schedulers (anacron, systemd timers with Persistent=true) catch up. Fourth, overlap: cron will start a new instance at the next firing minute even if the previous one is still running. Wrap your job in a lock (flock, Redis SETNX, or framework-level concurrency controls) if it isn't safely re-entrant.
Frequently Asked Questions
Find this useful?
These tools are free and ad-free. Support the project!