TinyFileLab

Home›Developer›Cron expression generator

Calculated in this page — nothing is transmitted

Cron expression generator

Five fields, one sentence of English, and the next ten times it will actually fire — including the day-of-week rule that most generators get wrong.

Common schedules

Type in any field, or paste a whole expression into the first one and it will be split across the five. Names work too: MON-FRI, JAN, and the shorthands @daily, @hourly, @weekly.

*/5 * * * *

Every 5 minutes

Valid five-field crontab syntax.

FieldYou wroteWhich means
Next runs
#Local timeFrom nowUTC

These are worked out in your browser's own time zone. A real cron daemon uses the server's zone, which is very often UTC — the section below explains how much trouble that difference causes.

Says what it will doA sentence of plain English plus the next ten timestamps, so you can check the schedule before it checks you.
Gets the day rule rightWhen both day fields are set, crontab means OR, not AND. This page follows that and tells you when it applies.
Names the dialectSix fields, L, W and # belong to Quartz. Paste one and you get a clear explanation instead of a wrong schedule.

Five fields, and the order everyone forgets

A crontab line is five space-separated fields followed by the command: minute, hour, day of month, month, day of week. Minutes run 0–59, hours 0–23, days of the month 1–31, months 1–12 or JAN–DEC, days of the week 0–7 or SUN–SAT, where both 0 and 7 mean Sunday. An asterisk means every value.

Within a field, , lists values, - makes a range, and / adds a step. So */15 is every fifteenth value starting at the bottom of the range, 9-17 is nine in the morning through five in the afternoon inclusive, and 1,15 is exactly two values. A step can follow a range as well: 0-30/10 fires at 0, 10, 20 and 30 and then stops until the next hour.

The trap: day of month and day of week

This is the rule that catches nearly everyone, and most online generators describe it wrongly. When both the day-of-month and the day-of-week fields are restricted — that is, neither is * — cron runs the job when either matches, not when both do.

0 0 13 * 5 does not mean “on Friday the 13th”. It means “on the 13th of every month, and also every Friday”, which is roughly sixty runs a year instead of one or two. This behaviour is written into the crontab manual page and has been in Vixie cron since the 1980s; the schedule preview above follows it, and says so whenever both fields are restricted. There is no expression that means “Friday the 13th”: the usual workaround is to schedule 0 0 13 * * and have the script itself exit early unless date +%u says 5.

The same rule is why the idiom for “the first Monday of the month” is 0 9 1-7 * 1 plus a check inside the script, rather than anything cron can express on its own. Quartz-style cron has # and L for this; plain crontab does not.

Steps that do not divide evenly

*/7 * * * * looks like “every seven minutes” and mostly behaves that way: it fires at 0, 7, 14, 21, 28, 35, 42, 49 and 56 minutes past. Then the hour rolls over and it fires at 0 again — four minutes after the last run, not seven. Steps are calculated inside each field independently, with no memory across the boundary, so any step that does not divide 60 produces a short interval every hour. The same applies to */7 in the hour field, which stumbles at midnight.

If you genuinely need an interval that is not a divisor of 60, you have two options: pick a value that does divide it (2, 3, 4, 5, 6, 10, 12, 15, 20 or 30), or use a systemd timer, which schedules on real elapsed time rather than on calendar fields. “Every 90 minutes” cannot be written as one crontab line at all; the usual fudge is two lines, 0 0,3,6,9,12,15,18,21 * * * and 30 1,4,7,10,13,16,19,22 * * *.

Which cron is this?

This page targets the five-field crontab used by Vixie cron, cronie and the BSDs — what you get on Linux and macOS, and what Kubernetes CronJob objects and most CI systems accept. Some relatives differ in ways that will bite you:

Quartz and Spring use six or seven fields, with seconds first, and add L (last), W (nearest weekday) and # (nth weekday of the month). In Quartz, one of the two day fields must be ? rather than *. Paste a six-field expression here and you will get a message saying so rather than a silent misreading. AWS EventBridge also uses six fields and requires the ?. GitHub Actions takes five fields but always interprets them as UTC, and will happily delay a job by several minutes when the runner queue is busy, so it is unsuitable for anything that must fire on the minute.

Time zones, and the two hours a year that break jobs

The table above is computed in your browser's zone, which is convenient and almost never where the job will run. A cron daemon uses the server's local zone, and on a cloud instance that is UTC unless somebody deliberately changed it. Kubernetes CronJobs use the controller's zone unless you set timeZone explicitly; container images are usually UTC too.

Then there is daylight saving. On the spring-forward day, the clock jumps from 01:59 to 03:00 and a job scheduled for 02:30 has no moment to run in. Vixie cron compensates for jobs scheduled once a day or less by running them once anyway, immediately after the jump; frequent jobs (anything with a wildcard minute) are simply skipped for that hour. On the autumn day the hour repeats, and daily jobs are deliberately not run twice, while frequent ones are. If a report absolutely must be generated once and only once per calendar day, schedule it somewhere between 04:00 and 23:00, or set the machine's zone to UTC and accept the shifting local time.

Common questions

What does */5 actually mean?

Every fifth value in that field, counting from the bottom of the range. In the minute field that is 0, 5, 10 and so on — not “five minutes after whenever the last run finished”. Steps that do not divide 60 leave a short gap at the end of each hour.

Why didn't my 2:30 am job run?

Almost certainly daylight saving. On the spring-forward date that minute does not exist in local time. Vixie cron re-runs daily jobs after the jump but skips wildcard-minute jobs entirely for that hour. Scheduling outside 01:00–03:00, or running the machine in UTC, avoids it.

My expression has six fields and this page rejects it.

Six fields means the first one is seconds, which is Quartz, Spring or AWS EventBridge syntax rather than crontab. Drop the seconds field and you have the crontab equivalent — you simply lose sub-minute precision, which crontab has never had.

Can cron run something every 30 seconds?

No. One minute is the finest resolution crontab has. The common workarounds are a systemd timer with OnUnitActiveSec, a loop inside the script with a sleep, or two crontab lines where the second one begins with sleep 30.

Does the next-run list use my time zone?

Yes, it uses whatever your browser reports, and it prints the UTC equivalent in the last column so you can compare against a server. The zone name is shown above the table. Nothing about the calculation is sent anywhere — it runs in this page.

What about @reboot and the other shorthands?

@hourly, @daily, @midnight, @weekly, @monthly and @yearly all expand into ordinary five-field expressions and are accepted here. @reboot is different: it runs once when cron starts, so there is no schedule to preview, and this page says so instead of inventing one.