Skip to content
All posts

Cron syntax explained: a no-nonsense guide

Cron is five fields in a line of text. This is what each one means, what the specials do, and why `0 0 * * 0` runs weekly.

DDDev DeskDeveloper Tools EditorPublished April 24, 20266 min readbeginner

# The shape

A cron expression is five fields separated by spaces, in this order:


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

A value of means "every". So runs every minute of every hour of every day.

# The operators

  • * — every
  • , — list: 0,15,30,45 runs at four specific minutes
  • - — range: 9-17 means 9 through 17 inclusive
  • / — step: */5 means every 5 (starting from 0), 10-20/2 means every 2 in the range 10–20

Combine freely: 0 9-17 MON-FRI = on the hour from 9am to 5pm, weekdays only.

<div class="callout callout-tip" role="note"><div class="callout-title">Tip</div><div class="callout-body"><p>When two of the day fields conflict, Vixie-cron uses <strong>OR</strong>, not AND. So <code>0 0 13 * FRI</code> runs on the 13th of the month <strong>or</strong> any Friday, not only Friday the 13th.</p></div></div>

# Common patterns

| Expression | Meaning |

|---|---|

| * | Every minute |

| /5 * | Every 5 minutes |

| 0 | Every hour, on the hour |

| 0 0 * | Every day at midnight |

| 0 9 1-5 | Weekdays at 9am |

| 0 0 1 | First of every month at midnight |

| 0 0 0 | Every Sunday at midnight |

| 0 0 1 1 * | New Year's midnight |

# Specials you probably don't want

  • @reboot — at system startup (not a time). Useful, but not portable.
  • 0 0 29 2 * — midnight on Feb 29. Runs once every 4 years. Not a bug.
  • /25 * — every 25 minutes starting at 0. So :00, :25, :50, then :00 again (not :75). The step resets at the boundary.

# Common mistakes

  • Forgetting cron jobs run in cron's minimal PATH — not your login shell's. Use absolute paths.
  • % must be escaped as \% in a crontab line (it's interpreted as stdin).
  • Jobs are silent unless you wire up email or a log file. >> /var/log/mything.log 2>&1 is your friend.

# Try it

Paste any cron expression into our Cron Explainer to see exactly when it runs in plain English — and to validate syntax before you commit to a crontab.

Frequently asked questions

What timezone does cron use?

Classical Unix cron uses the system timezone. On Linux that's whatever `/etc/localtime` points at. Docker containers usually inherit UTC unless you mount your host's timezone.

Why doesn't my cron job run?

Four usual suspects: (1) the PATH differs in cron's shell, (2) the job writes to stderr and nobody's reading it, (3) the `% character` wasn't escaped, (4) the timezone isn't what you think.

What are the `@yearly`, `@daily`, `@hourly` shortcuts?

Vixie-cron extensions: `@yearly` = `0 0 1 1 *`, `@monthly` = `0 0 1 * *`, `@weekly` = `0 0 * * 0`, `@daily` = `0 0 * * *`, `@hourly` = `0 * * * *`, `@reboot` = at startup.

New posts, once a week.

Practical developer guides. No spam. Unsubscribe any time.

Tools mentioned

Keep reading