⏰ Cron Cheat Sheet

Everything you need to write and read cron schedules. Open the matching cron parser to see the next few run times for any expression you build here.

Updated October 2026 · covers Vixie cron / crontab(5), Quartz, Kubernetes CronJob, GitHub Actions, Vercel Cron, systemd timers.

Contents

🏗️ Field structure

5-field cron (classic Unix, Kubernetes, GitHub Actions, Vercel):

┌───────────── minute        (0-59)
│ ┌─────────── hour          (0-23)
│ │ ┌───────── day of month  (1-31)
│ │ │ ┌─────── month         (1-12 or JAN-DEC)
│ │ │ │ ┌───── day of week   (0-6 or SUN-SAT, 0=Sunday)
│ │ │ │ │
* * * * *

6-field cron (Quartz, Spring, some AWS):

┌───────────── second        (0-59)   ← extra field
│ ┌─────────── minute        (0-59)
│ │ ┌───────── hour          (0-23)
│ │ │ ┌─────── day of month  (1-31)
│ │ │ │ ┌───── month         (1-12)
│ │ │ │ │ ┌─── day of week   (1-7 in Quartz, 1=Sunday)   ← note offset
│ │ │ │ │ │
* * * * * *

7-field cron (Quartz, with optional year):

second  minute  hour  day-of-month  month  day-of-week  year(optional 1970-2099)
Day-of-week confusion: classic cron uses 0-6 with 0 = Sunday. Quartz uses 1-7 with 1 = Sunday. Some systems accept both 0 and 7 for Sunday. If you aren't sure, write the day name: SUN, MON, etc.

🔣 Special characters

CharacterMeaningExample
*Any value in that field* * * * * → every minute
,List of values0,15,30,45 * * * * → every 15 min
-Range0 9-17 * * * → every hour 9am-5pm
/Step value — "every N"*/15 * * * * → every 15 min
?No specific value (Quartz only; one of day-of-month / day-of-week must be ?)0 0 12 ? * MON
LLast — "last day of month" or "last Friday" (Quartz, AWS)0 0 L * ? → last day of each month
WNearest weekday to the given day-of-month (Quartz, AWS)0 0 15W * ? → nearest weekday to the 15th
#Nth weekday of the month (Quartz)0 0 ? * MON#2 → 2nd Monday

⚡ Shortcuts (nicknames)

ShortcutEquivalent toMeans
@yearly0 0 1 1 *Once a year, Jan 1 at 00:00
@annually0 0 1 1 *Alias for @yearly
@monthly0 0 1 * *First of each month at 00:00
@weekly0 0 * * 0Every Sunday at 00:00
@daily0 0 * * *Every day at 00:00
@midnight0 0 * * *Alias for @daily
@hourly0 * * * *Top of every hour
@reboot—Run once at crond startup. Not supported by Quartz / k8s / most managed cron.
@every 15m—Go's robfig/cron syntax; not standard

🧪 40+ copy-paste examples

5-field classic cron unless marked otherwise. Paste any of these into our cron parser to see the next few run times.

Every N minutes

Every minute
* * * * *
Every 5 minutes
*/5 * * * *
Every 15 minutes
*/15 * * * *
Every 30 minutes
*/30 * * * *
At minute 10 past every hour
10 * * * *

Every N hours

Every hour
0 * * * *
Every 2 hours
0 */2 * * *
Every 6 hours (00, 06, 12, 18)
0 */6 * * *
Every hour during business hours (9-17)
0 9-17 * * 1-5
Weekdays only.

Daily

Every day at midnight
0 0 * * *
Every day at 6:30 am
30 6 * * *
Twice a day (6am and 6pm)
0 6,18 * * *
Every weekday at 8:00 am
0 8 * * 1-5
Every weekend at 10am
0 10 * * 6,0
Or 0 10 * * SAT,SUN.

Weekly

Every Monday at 9am
0 9 * * 1
Every Friday at 5pm
0 17 * * 5
Every Sunday night at 23:30
30 23 * * 0
Mon/Wed/Fri at noon
0 12 * * MON,WED,FRI

Monthly

First of every month at midnight
0 0 1 * *
15th of every month at 09:00
0 9 15 * *
Last day of each month at midnight (Quartz)
0 0 0 L * ?
Last Friday of each month at 17:00 (Quartz)
0 0 17 ? * 6L
Nearest weekday to the 15th at 09:00 (Quartz)
0 0 9 15W * ?
2nd Tuesday of each month at 10:00 (Quartz)
0 0 10 ? * TUE#2

Quarterly / Yearly

First day of each quarter at midnight
0 0 1 1,4,7,10 *
First day of each year at midnight
0 0 1 1 *
Or @yearly.
Every July 1st at 09:00
0 9 1 7 *

Business-hours heartbeats

Every 15 min, 9-5 weekdays
*/15 9-17 * * 1-5
Every 5 min, 24/7
*/5 * * * *
Every 30 min on weekdays except lunch (9-12, 13-17)
*/30 9-11,13-16 * * 1-5
Add a 30 11 * * 1-5 plus 0,30 12 * * 1-5 if you need every :00 and :30 too.

Backup / housekeeping

Nightly backup at 02:30
30 2 * * *
Weekly backup Sunday 03:00
0 3 * * 0
Clean temp files hourly at :45
45 * * * *
Rotate logs daily at 00:05
5 0 * * *

Spread-the-load tricks

Avoid "top of the hour" stampede — random minute
17 * * * *
Any random minute is better than :00 if a lot of jobs run hourly.
Every 4 hours offset by 1 (01, 05, 09, 13, 17, 21)
0 1-23/4 * * *

🖥️ Platform differences

PlatformFieldsDoWSmallest unitMax frequencyNotes
Vixie cron / crontab(5)50-7, 0 & 7 = Sunminuteevery minuteSupports @reboot. Shell env matters.
Quartz / Spring6-71-7, 1 = Sunsecondevery secondSupports L W # ?. Must use ? for one of DoM / DoW.
Kubernetes CronJob50-6, 0 = Sunminuteevery minuteTimezone field (.spec.timeZone) GA since 1.27.
GitHub Actions50-6, 0 = Sun5 minutesevery 5 minRuns UTC. Up to ~15 min late during peak.
Vercel Cron50-6, 0 = Sunminute (Pro+)varies by planRuns UTC. Hobby plan is daily minimum.
AWS EventBridge / CloudWatch61-7, 1 = Sunminuteevery minuteMust use ? for one of DoM / DoW. UTC only.
systemd timer— (its own format)Mon,Tue…second< secondNot cron syntax at all. Uses OnCalendar=.
Go robfig/cron5 or 60-6second (optional)every secondSupports @every 30s syntax.

🌍 Time zones

Classic cron runs in the system's time zone. Managed cron almost always runs in UTC. For "every day at 9am local time" to actually happen at 9am local, you need to either:

DST gotcha: on the spring-forward night, 02:00-03:00 doesn't exist locally — any cron job scheduled there just doesn't run. On fall-back night, 02:00-03:00 happens twice — most cron implementations avoid re-running, but check your platform's docs.

⚠️ Gotchas

DoM vs DoW OR, not AND

If you set both day-of-month and day-of-week to non-*, classic cron runs when either matches (OR). So 0 0 1 * MON fires on the 1st of every month and every Monday. Quartz uses AND, which is why it forces ? on one of them.

Env vars are different in cron

Cron runs with a minimal environment — no $PATH customizations, no .bashrc, often no $HOME. Reference binaries by absolute path, or source your profile at the top of the script.

Missing newline at the end of crontab

Vixie cron silently ignores the last line if it doesn't end with a newline. Always leave a trailing newline.

No overlap protection by default

If a job runs long enough that the next scheduled run starts before it finishes, you'll have two copies running. Wrap long jobs in flock or similar.

Output goes to email, not stdout

Any output a cron job produces is mailed to the user — unless you redirect to a log or /dev/null. Add >> /var/log/myjob.log 2>&1.

🧰 Related tools