Skip to main content

Interactive tool

What that cron line actually does

Field by field in plain language, the next five times it fires, and a warning about the one rule that makes a schedule run far more often than its author intended.

Runs in your browser · nothing is sent anywhere

Try

Runs every 15 minutes, every hour, every day.

FieldValueMeans
Minute*/15every 15 minutes
Hour*every hour
Day of month*every day of the month
Month*every month
Day of week*every day of the week

Next five runs

Calculating from the current time…

What a cron expression is

Cron is the scheduler that runs jobs at set times on Unix-like systems, and a cron expression is how you write the schedule. It is five fields separated by spaces:

minute hour day-of-month month day-of-week

Each field is either a specific value, a list, a range, or * meaning “every”. So 0 2 * * * is minute 0, hour 2, every day of the month, every month, every day of the week — two in the morning, daily.

Using it

Paste an expression and read the table: each field, what you wrote, and what it means. The next five run times are computed from now, so you can check a schedule does what you meant before committing it.

These five fields are the same dialect in a system crontab, a Kubernetes CronJob schedule and most CI schedulers, so an expression checked here is the one you can paste into any of them. The note under the run times covers the timezone question, which is the other half of why a job fires at an unexpected hour.

If a schedule can never run, it says so rather than showing an empty list. 0 0 30 2 * is accepted by cron and fires never, because there is no 30th of February.

The union rule, and other things that surprise people

When both the day-of-month and day-of-week fields are restricted, cron takes the union and not the intersection. 0 12 1 * 1 does not mean “the first of the month, if it is a Monday”. It means “the first of the month, and also every Monday” — roughly five times a month rather than once or twice a year.

This catches people because every other pair of fields is an intersection, and because the mistake makes a job run more often rather than failing. If you want the intersection, cron cannot express it: test the date inside the job and exit early.

Both 0 and 7 mean Sunday, so 1-7 is every day and not Monday to Sunday-as-distinct. A step on a bare value means “from here onwards”: 5/10 in the minute field is 5, 15, 25 and so on, not “every 10 minutes starting at 5” bounded to the hour.

Six fields usually means a Quartz expression with seconds at the front, which is a different dialect — this reads the standard five.

Questions people ask about this

Does 0 12 1 * 1 run on the first of the month or on Mondays?

Both. That is the trap.

When the day-of-month and day-of-week fields are both restricted, cron takes the union rather than the intersection. So 0 12 1 * 1 fires at noon on the 1st and at noon every Monday — around five times a month, not the once or twice a year that “the first, if it is a Monday” would give.

Cron cannot express the intersection. If that is what you want, test the date inside the job and exit early. The explainer flags this whenever both fields are restricted, because the mistake makes a job run more often rather than fail, so nothing else will tell you.

Are the next run times in my timezone?

No — they are UTC. Showing them in your browser's timezone would be misleading, because a crontab runs in the server's timezone and that is rarely the same as yours.

Check the server with timedatectl, and look for a CRON_TZ line at the top of the crontab, which overrides it for the entries below. Timezone confusion and the union rule between them account for most schedules that fire at an hour nobody expected.

What is the difference between */15 and 5/15?

*/15 in the minute field is every 15 minutes from 0 — 0, 15, 30, 45. 5/15 means the same step but starting at 5, so 5, 20, 35, 50. A step written on a bare value means “from here onwards” rather than “every N within this value”, which is worth knowing because 0/15 and */15 are identical while 5/15 quietly shifts every run.

Why does my schedule never run?

Almost always because it asks for a date that does not exist. cron accepts 0 0 30 2 * without complaint and it fires never, since there is no 30th of February; 0 0 31 4 * is the same for April. The explainer says so explicitly instead of showing an empty list of next runs, which would look like a bug in the tool rather than a bug in the schedule. A related case is 0 0 29 2 *, which does run — but only in leap years, so the next occurrence can be three years away.

My expression has six fields. Why is it rejected?

Six fields usually means a Quartz expression, which puts seconds at the front and is used by Java schedulers and Spring @Scheduled. This reads the standard five-field cron used by crontab, Kubernetes CronJob and most CI schedulers. Quartz also uses ? in the day fields, which is accepted here and treated as *, and it supports L and #, which standard cron does not.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere