Cron Expression Parser & Generator
Decode any cron expression into plain English and preview the next scheduled run times. Build cron schedules for Linux, Kubernetes CronJobs, GitHub Actions, and more.
Runs every 5 minutes
The cron expression is made of five fields. Each field can have the following values.
| * | * | * | * | * |
|---|---|---|---|---|
| minute (0 to 59) | hour (0 to 23) | day of month (1 to 31) | month (1 to 12) | day of week (0 to 6) |
Here are some examples for you.
| Cron expression | Schedule |
|---|---|
| * * * * * | Every minute |
| 0 * * * * | Every hour |
| 0 0 * * * | Every day at 12:00 AM |
| 0 9 * * 1-5 | At 9:00 AM, weekdays only |
| 0 0 * * 5 | At 12:00 AM, only on Fridays |
| 0 0 1 * * | At 12:00 AM, on day 1 of the month |
| 0 0 1 1,4,7,10 * | At 12:00 AM, 1st day of each quarter |
| */15 * * * * | Every 15 minutes |
| 30 6 * * 1,3,5 | At 6:30 AM, Mon / Wed / Fri |
Click any row to try it.
How to use the cron expression parser
Four steps. Everything runs in your browser, and the next run times are calculated from your own clock.
Type the five fields
Minute, hour, day of month, month, day of week, in that order and separated by spaces.
30 2 * * 1is half past two on Mondays. If you are unsure of the order, start from the example and change one field at a time.Read it back in English
The plain-English line is the check that matters. An expression can be perfectly valid and still not mean what you intended, and reading "at 02:30 on Monday" catches that in a way that staring at five numbers does not.
Check the next run times
The upcoming runs are where off-by-one mistakes show up.
0 0 * * 7and0 0 * * 0both mean Sunday;0 * * * *runs hourly but* 0 * * *runs sixty times during midnight hour. The dates tell you which one you wrote.Put it where it runs
For a Linux host,
crontab -eand paste the line with the command after it. For Kubernetes, it goes inspec.scheduleon a CronJob. For GitHub Actions, inon.schedule.cron, where the times are always UTC.
The cron rules that catch people out
Cron syntax is small enough to learn in a minute and has about ten behaviours that surprise people for years. These are the ten.
Day of month and day of week together
When both fields are restricted, cron runs the job if either matches, not both.
This is the one that surprises nearly everyone. 0 0 13 * 5 is not "Friday the 13th", it is "every 13th of the month, and also every Friday". To get a real conjunction you have to test the date inside the command itself.
The timezone
A cron entry runs in whatever timezone the thing running it uses.
System crontab follows the host clock, a Kubernetes CronJob follows the controller manager unless you set spec.timeZone, and GitHub Actions is always UTC with no way to change it. A nightly job scheduled at 0 0 * * * from London runs at midnight UTC, which is 01:00 local in summer.
Daylight saving time
Twice a year, one local hour does not happen and another happens twice.
A job at 0 2 * * * can be skipped entirely on the spring change or run twice in autumn, depending on the cron implementation. Schedule anything that must not double-run outside 01:00 to 03:00, or make the job idempotent.
Step values with */
*/15 means every 15 units starting from zero within that field.
It restarts each hour rather than running continuously, so */40 * * * * fires at :00 and :40 and then again at :00, forty minutes apart and then twenty. Steps only divide evenly when they are a factor of 60.
Zero and seven are both Sunday
The day-of-week field runs 0 to 6 from Sunday, and most implementations also accept 7 for Sunday.
Monday is 1, so a week counted from Monday is off by one against the field. Three-letter names (MON, SUN) are accepted by most cron implementations and are much harder to misread.
A minute field of * rather than 0
The leftmost field is minutes, and * means every minute.
* 3 * * * runs sixty times between 03:00 and 03:59, not once at three. If you meant once, the minute field needs a number. This is the most common way an accidental hammering job gets written.
Five fields, not six
Standard Unix cron, Kubernetes CronJobs and GitHub Actions all take five fields.
Quartz, Spring and several cloud schedulers take six or seven, with seconds at the front and sometimes a year at the end. A six-field expression pasted into crontab is rejected, and a five-field one pasted into Quartz means something else entirely.
Shorthand such as @daily and @reboot
@yearly, @monthly, @weekly, @daily and @hourly stand in for the common schedules, and @reboot runs once at startup.
@daily is midnight exactly, so every service using it stampedes at the same moment. Spread them out with a real expression. @reboot is not supported by Kubernetes CronJobs at all, and on systemd hosts it can fire before the network is up.
The environment a cron job runs in
Cron gives the job a minimal environment, not your login shell.
PATH is short, your shell profile is not sourced, and $HOME may not be what you expect, so a command that works in your terminal fails silently under cron. Use absolute paths for everything and redirect output to a file so there is something to read when it fails.
Overlapping runs
Cron starts the next run on schedule whether or not the previous one has finished.
A five-minute job on a */5 schedule eventually runs two copies at once, then three. Use flock on Linux, or concurrencyPolicy: Forbid on a Kubernetes CronJob, rather than assuming the job will always be quick.
Cron expression questions people actually ask
How do I read a cron expression?
Left to right: minute, hour, day of month, month, day of week. 15 14 1 * * is 14:15 on the first of every month. * means every value for that field, a comma lists values, a hyphen gives a range, and / gives a step. If it takes more than a glance, paste it above and read the English.
What does */5 * * * * mean?
Every five minutes, at :00, :05, :10 and so on through the hour. The step restarts each hour, so a step that does not divide 60 evenly produces an uneven gap at the top of the hour.
What timezone do cron jobs run in?
Whatever the scheduler uses. Linux crontab follows the host timezone, which on most servers is UTC. A Kubernetes CronJob follows the controller manager unless you set spec.timeZone, available since Kubernetes 1.27. GitHub Actions schedules are always UTC. Check it rather than assuming, because the answer differs by an hour twice a year.
Why does my cron job not run?
In order of likelihood: the command works in your shell but not in cron's minimal environment, so use absolute paths; the crontab line has no trailing newline; the script is not executable; or % appears unescaped in the command, which cron treats as a newline. Redirect output to a file and the reason is usually in it.
How do I run a cron job on the last day of the month?
Standard cron cannot express it, because there is no L in the day-of-month field. Run it daily and let the command exit early unless it is the last day: 0 0 * * * [ "$(date -d tomorrow +%d)" = "01" ] && /path/to/job. Quartz-style schedulers do support L.
Is this the same syntax as a Kubernetes CronJob?
Yes. spec.schedule on a Kubernetes CronJob takes the same five fields. The differences are around it rather than in it: set spec.timeZone explicitly, set concurrencyPolicy so a slow run cannot overlap the next, and set startingDeadlineSeconds so a missed window does not fire late.
Scheduling, in practice
Learn Linux Cron Jobs: Step by Step
Cron is a core Linux skill. Our free Linux tutorials teach you scheduling, automation, and much more.