cronsaidwhat.com Runs in your browser
Common schedules

Cron expression examples

The schedules people actually need, grouped by how often they run — each one described by the same parser the explainer uses, so the wording is never out of date.

Cron expression reference

Every description below comes from the parser rather than a written label. Open any expression in the explainer to see when it fires next.

Every few minutes

Step values divide the hour evenly only when the step divides 60. */7 restarts at the top of every hour, so the gap between 56 and the next run is four minutes, not seven.

* * * * *
Every minute Every minute, every day.
Open
*/2 * * * *
Every 2 minutes Every 2 minutes, every day.
Open
*/5 * * * *
Every 5 minutes Every 5 minutes, every day.
Open
*/10 * * * *
Every 10 minutes Every 10 minutes, every day.
Open
*/15 * * * *
Every quarter hour Every 15 minutes, every day.
Open
*/30 * * * *
Every half hour At 00 minutes past and 30 minutes past of every hour, every day.
Open
*/7 * * * *
Every 7 minutes — the uneven case Every 7 minutes, every day.
Open

Hourly

Leaving the minute as * is the single most common cron mistake: it runs sixty times an hour, not once. Pin the minute.

0 * * * *
Every hour, on the hour Every hour at 00 minutes past, every day.
Open
15 * * * *
Every hour at quarter past Every hour at 15 minutes past, every day.
Open
0 */2 * * *
Every 2 hours Every 2 hours at 00 minutes past, every day.
Open
0 */6 * * *
Every 6 hours Every 6 hours at 00 minutes past, every day.
Open
0 9-17 * * *
Hourly during business hours At 09:00, 10:00, 11:00, 12:00, 13:00, 14:00, 15:00, 16:00, and 17:00, every day.
Open
0,30 * * * *
Twice an hour At 00 minutes past and 30 minutes past of every hour, every day.
Open

Daily

A job scheduled between 01:00 and 03:00 can run twice or not at all on daylight-saving changeover days. Pick a time outside that window for anything that must not repeat.

0 0 * * *
Every day at midnight At 00:00, every day.
Open
0 6 * * *
Every day at 06:00 At 06:00, every day.
Open
30 4 * * *
Every day at 04:30 At 04:30, every day.
Open
0 12 * * *
Every day at noon At 12:00, every day.
Open
0 9,17 * * *
Twice a day At 09:00 and 17:00, every day.
Open
0 0 * * 1-5
Every weekday at midnight At 00:00, on Monday, Tuesday, Wednesday, Thursday, and Friday.
Open

Weekly

Sunday is both 0 and 7. Both are accepted, and 1-5 is Monday to Friday — the week starts on Sunday, which trips people up when writing ranges.

0 0 * * 0
Every Sunday at midnight At 00:00, on Sunday.
Open
0 9 * * 1
Every Monday at 09:00 At 09:00, on Monday.
Open
0 17 * * 5
Every Friday at 17:00 At 17:00, on Friday.
Open
0 9 * * 1-5
Every weekday at 09:00 At 09:00, on Monday, Tuesday, Wednesday, Thursday, and Friday.
Open
0 10 * * 6,0
Weekends at 10:00 At 10:00, on Sunday and Saturday.
Open
0 3 * * 2,4
Tuesdays and Thursdays at 03:00 At 03:00, on Tuesday and Thursday.
Open

Monthly and yearly

Day 31 simply does not fire in months that lack it — there is no rounding. To catch the true end of a month, run daily and check the date in your own code.

0 0 1 * *
First of every month At 00:00, on the 1st.
Open
0 0 15 * *
Fifteenth of every month At 00:00, on the 15th.
Open
0 0 1 */3 *
Quarterly At 00:00, on the 1st in January, April, July, and October.
Open
0 0 1 1 *
Once a year, on 1 January At 00:00, on the 1st in January.
Open
0 0 31 * *
The 31st — skips short months At 00:00, on the 31st.
Open
0 4 1 * 1
Both day fields set — an OR, not an AND At 04:00, on the 1st or on Monday (whichever matches).
Open

The five fields, in order

Every expression above is five fields separated by spaces, and they always appear in the same order: minute (0–59), hour (0–23), day of month (1–31), month (1–12), and day of week (0–6, where 0 is Sunday). An asterisk means "every value", so the four asterisks in */5 * * * * are doing the work of saying "every hour of every day of every month".

Within a field you can write a single number, a list (1,15), a range (9-17), or a step (*/10, or 9-17/2 to step within a range). That is the entire syntax. Everything else that looks complicated is a combination of those four things.

The four mistakes that account for most of them

  • Leaving the minute as an asterisk. * 3 * * * does not run at three o'clock — it runs sixty times, once a minute, for the whole of the 03:00 hour. If a field is more specific than the one to its left, the left one almost always needs pinning.
  • Assuming steps divide evenly. */7 restarts its count at the top of every hour, so it fires at :00, :07 … :56, and then again four minutes later at :00. Only steps that divide 60 — 2, 3, 4, 5, 6, 10, 12, 15, 20, 30 — produce an even rhythm across the hour boundary.
  • Reading the two day fields as AND. When both the day of month and the day of week are restricted, cron ORs them. 0 4 1 * 1 runs on the first of the month and on every Monday, not on first-of-the-month-if-Monday.
  • Forgetting the timezone. Kubernetes, GitHub Actions, and most cloud schedulers interpret schedules in UTC unless told otherwise, so a schedule written for local business hours will fire at a different local time — and will drift by an hour when daylight saving changes, because UTC does not.

Daylight saving, and why 02:30 is a bad time

On a machine running in a timezone that observes daylight saving, the hour between 01:00 and 03:00 is not a normal hour twice a year. In spring it does not exist — the clock jumps straight past it — so a job scheduled at 02:30 does not run at all. In autumn it happens twice, so the same job runs twice. Different cron implementations handle this differently, and none of them handles it in a way you would want to depend on. Schedule anything important outside that window, or run the scheduler in UTC.

To check a specific expression against real dates, paste it into the explainer, which lists the next several fire times. To build one from scratch without memorising the field order, use the builder.

Common questions

What is the cron expression for every 5 minutes?

*/5 * * * * — the */5 in the minute field means "every fifth minute starting from zero", so it fires at :00, :05, :10 and so on through :55. The four asterisks after it mean every hour, every day of the month, every month, and every day of the week. Note that this only divides the hour evenly because 5 divides 60; a step like */7 restarts its count at the top of each hour, so the gap from :56 to the next run is four minutes rather than seven.

How do I run a job once a day?

Pin both the minute and the hour: 0 3 * * * runs at 03:00 every day. The mistake to avoid is leaving the minute as an asterisk — 0 * * * * is hourly, but * 3 * * * runs sixty times, once every minute between 03:00 and 03:59. If the job must not run twice, avoid scheduling it between 01:00 and 03:00, because that window is repeated on the day the clocks go back and skipped on the day they go forward.

Why does my job with both a date and a weekday run more often than expected?

Because when the day-of-month and day-of-week fields are both restricted, cron treats them as OR rather than AND. 0 4 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". This is a genuine quirk of the format rather than an implementation detail, and it is inherited by almost every cron-compatible scheduler. To get the AND behaviour, schedule the weekday and test the date inside your own job.

Which day is 0 — Sunday or Monday?

Sunday. The week runs 0 for Sunday through 6 for Saturday, and 7 is also accepted as Sunday, so both 0 and 7 work. The practical consequence is that 1-5 is Monday to Friday, which is what you want for weekdays, while 0-4 is Sunday to Thursday and is almost never what anyone means. Weekends are 6,0 or equivalently 0,6.

What happens on the 31st in a month that has 30 days?

Nothing — the job simply does not run that month. There is no rounding down to the last day and no catch-up; the schedule matches a date that does not exist, so it never fires. The same applies to 29 February in three years out of four. If you need the actual end of the month, schedule the job daily and have it exit early unless tomorrow is the first, which is the only reliable way to express it in five fields.

Do these work in Kubernetes and GitHub Actions?

Yes for all the standard five-field expressions on this page. Kubernetes CronJob and GitHub Actions both use the same syntax, as do most cloud schedulers. Two differences worth knowing: neither supports the non-standard @reboot shortcut, and both interpret schedules in UTC by default rather than in the machine's local timezone, so a job written for 09:00 local will fire at a different local hour unless you set the timezone explicitly.