← Cheat Sheets

Cron Expression Cheat Sheet

A cron expression has five space-separated fields. Together they define every moment a scheduled job fires.

The five fields

FieldAllowed valuesSpecial characters
Minute0–59* , - /
Hour0–23* , - /
Day of month1–31* , - / ? L W
Month1–12 or JAN–DEC* , - /
Day of week0–7 (0 and 7 = Sunday) or SUN–SAT* , - / ? L #

Special characters

CharMeaningExample
*Every allowed value* * * * * — every minute
,Value list separator0 8,20 * * * — 8:00 and 20:00 daily
-Range0 9 * * 1-5 — 9:00 on weekdays
/Step within a range*/10 * * * * — every 10 minutes
LLast day (of month/week)0 0 L * * — last day of the month
#Nth weekday of the month0 0 * * 1#1 — first Monday of the month

The schedules everyone copies

ExpressionMeans
* * * * *Every minute — recipe
*/5 * * * *Every 5 minutes — recipe
*/10 * * * *Every 10 minutes — recipe
*/15 * * * *Every 15 minutes — recipe
*/30 * * * *Every 30 minutes — recipe
0 * * * *Every hour, on the hour — recipe
0 0 * * *Midnight every day — recipe
0 9 * * 1-59:00 AM, Monday to Friday — recipe
0 10 * * 6,010:00 AM, weekends only — recipe
0 0 1 * *Midnight on the 1st of every month — recipe
59 23 L * *23:59 on the last day of the month — recipe
30 2 * * 02:30 AM every Sunday
0 0 1 1 *Midnight on January 1st (yearly)

FAQ

Which timezone does cron use?
The system timezone of the machine running crontab — usually UTC on servers. Cloud schedulers (GitHub Actions, Vercel) are UTC unless configured otherwise, which is the single most common cause of "my job ran at the wrong time".

Is Sunday 0 or 7?
Both, in most implementations. That is why 0 and 7 are listed as valid — but mixing them in ranges (6-7 vs 6-0) produces different days, so pick one convention and stick to it.

Why did */5 in the day-of-month field surprise me?
Steps restart at the field minimum. */5 in day-of-month fires on the 1st, 6th, 11th… — not "every 5 days from today".

Try it instead of memorizing it

Build it visually in the Cron Expression Editor