🍱 Lunchbox Hands

cron

Cron Syntax Cheat Sheet: Fields, Examples & Special Strings

A clear cron cheat sheet: what each of the five fields means, the special characters, @daily-style shortcuts, ready-to-use schedule examples, and the day-of-week gotcha that catches everyone.

Cron expressions look like line noise until you see the structure. There are just five fields, each a slot in time, read left to right. Here’s the whole system on one page.

The five fields

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ minute        (0–59)
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ hour        (0–23)
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ day of month (1–31)
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ month   (1–12)
β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ day of week (0–7, Sun = 0 or 7)
β”‚ β”‚ β”‚ β”‚ β”‚
* * * * *   command to run

So 30 8 * * 1 = β€œat 08:30, on every day-of-month, every month, but only on Mondays.”

Special characters

SymbolMeaningExample
*every value* * * * * = every minute
,list of values0 9,17 * * * = 09:00 and 17:00
-range0 9-17 * * * = every hour 09:00–17:00
/step*/15 * * * * = every 15 minutes
*/nevery n units0 */6 * * * = every 6 hours

You can combine them: 0 0-23/2 * * * runs every 2 hours, on the hour.

Special strings (the readable shortcuts)

Most cron implementations accept these in place of the five fields:

StringEquivalentMeaning
@yearly / @annually0 0 1 1 *Once a year, Jan 1 00:00
@monthly0 0 1 * *First of the month, 00:00
@weekly0 0 * * 0Sundays, 00:00
@daily / @midnight0 0 * * *Every day, 00:00
@hourly0 * * * *Top of every hour
@rebootβ€”Once, at startup

Common schedules, copy-paste ready

ScheduleCron
Every minute* * * * *
Every 5 minutes*/5 * * * *
Every 30 minutes*/30 * * * *
Every hour0 * * * *
Every day at 02:000 2 * * *
Every weekday at 09:000 9 * * 1-5
Every Monday at 08:3030 8 * * 1
First of every month, 00:000 0 1 * *
Twice a day (00:00 & 12:00)0 0,12 * * *
Every 15 min, business hours, weekdays*/15 9-17 * * 1-5

The gotchas that bite everyone

1. Day-of-month and day-of-week are OR’d, not AND’d. When both field 3 (day of month) and field 5 (day of week) are restricted, cron runs when either matches β€” not both. So 0 0 13 * 5 runs on the 13th and on every Friday, not just β€œFriday the 13th.” If you need both conditions, you usually have to check inside the script.

2. Sunday is both 0 and 7. 0 and 7 both mean Sunday. Some systems also accept three-letter names (SUN, MON, …) and month names (JAN, FEB, …).

3. Timezone. Classic cron runs in the server’s local timezone (or UTC on many containers). A 0 0 * * * job is midnight somewhere β€” confirm which, especially around daylight-saving shifts, when a local-time job can run twice or get skipped.

4. */n doesn’t always divide evenly. */40 * * * * fires at minute 0 and 40, then resets at the next hour β€” so the gap between the :40 run and the next :00 run is only 20 minutes, not 40. Steps count from 0 within each field, they don’t roll over.

Test before you trust it

A wrong cron expression fails silently β€” the job just never runs when you expect. Before committing one to a server or CI config:

  • Decode an existing expression in plain English with the Cron Parser β€” paste any cron string and see exactly when it fires next.
  • Build one visually with the Crontab Builder β€” pick the schedule you want and get the correct expression out, no guessing.

Both run in your browser. Get the expression right once, and you never have to wonder whether last night’s job actually ran.