Developer Tools

Cron Expressions Explained: Read & Write a Crontab

PAYATE Team· · 5 min read
Cron Expressions Explained: Read & Write a Crontab

Cron is the quiet scheduler that runs most of the recurring jobs on the internet — backups, report emails, cache refreshes, cleanup tasks. The one thing that trips everyone up is its cryptic five-field schedule, like 0 2 * * 1. This guide teaches you to read and write any cron expression with confidence, with plenty of real examples.

What cron and a crontab are

Cron is a time-based job scheduler on Unix-like systems. A crontab ("cron table") is the list of jobs it should run, each with a schedule and a command. Every minute, cron checks the table and runs anything whose schedule matches the current time. It is how a server can, say, email you a summary every Monday at 2 AM without anyone being there to press a button.

To build and read schedules visually, use our Cron Expression Parser — it translates any expression into plain English and shows the next run times.

The five fields

A standard cron schedule has five fields, separated by spaces, in this order:

* * * * *
| | | | |
| | | | +-- Day of week   (0-6, Sunday = 0)
| | | +---- Month         (1-12)
| | +------ Day of month  (1-31)
| +-------- Hour          (0-23)
+---------- Minute        (0-59)

Each field says "when, within this unit, should the job run." A * means "every" value of that field. So * * * * * means "every minute of every hour of every day" — once a minute, forever.

The special characters

SymbolMeaningExampleReads as
*Every value* * * * *Every minute
,A list of values0 8,12,18 * * *At 8, 12 and 18:00
-A range0 9-17 * * *Every hour from 9 to 17
/A step/interval*/15 * * * *Every 15 minutes

You can combine them: 0 9-17/2 * * 1-5 means "every 2 hours between 9 and 17, Monday to Friday."

Reading an expression: a worked example

Take 30 2 * * 1 and read it field by field:

  • Minute = 30 → at minute 30
  • Hour = 2 → of the 2 AM hour
  • Day of month = * → any day of the month
  • Month = * → any month
  • Day of week = 1 → but only on Monday

Put together: "At 02:30 every Monday." That is a classic schedule for a weekly backup or report.

Common schedules you can copy

ExpressionWhen it runs
*/5 * * * *Every 5 minutes
0 * * * *Every hour, on the hour
0 0 * * *Every day at midnight
30 9 * * 1-509:30, Monday to Friday
0 0 1 * *Midnight on the 1st of every month
0 0 * * 0Midnight every Sunday
0 */6 * * *Every 6 hours
0 0 1 1 *Once a year, on 1 January

The day-of-month vs. day-of-week trap

This is the most misunderstood part of cron. When you set both the day-of-month and the day-of-week fields (neither is *), most cron implementations treat it as OR, not AND. So 0 0 13 * 5 runs on the 13th of the month or on every Friday — not only on Friday the 13th. If you need a precise rule, leave one of the two fields as * and test it with a cron parser before you rely on it.

Handy shortcuts and extensions

Many systems accept named shortcuts instead of five fields:

  • @hourly = 0 * * * *
  • @daily (or @midnight) = 0 0 * * *
  • @weekly = 0 0 * * 0
  • @monthly = 0 0 1 * *
  • @yearly (or @annually) = 0 0 1 1 *
  • @reboot = run once when the server starts

Some schedulers (Quartz, and many cloud platforms) add a seconds field at the front, making six fields, plus extras like ?, L (last) and # (nth weekday). Always check which flavour your platform uses.

Tips for reliable cron jobs

  • Use absolute paths. Cron runs with a minimal environment, so /usr/bin/php /home/user/app/cron.php is safer than a bare command.
  • Mind the timezone. Cron usually runs in the server's timezone — know whether that is UTC or local. Our Timezone Converter helps you plan runs across zones, and times are often stored as a Unix timestamp under the hood.
  • Capture output. Redirect to a log (>> /path/log 2>&1) so a silent failure does not go unnoticed.
  • Prevent overlaps. Use a lock file so a slow job does not start a second copy before the first finishes.
  • Test the expression first with a Cron Parser so you are certain of the next run times.

Frequently asked questions

What does * * * * * mean?

Every minute of every hour of every day — the job runs once a minute, continuously. It is rarely what you want in production; a step like */5 is more common.

Is Sunday 0 or 7 in cron?

Sunday is 0 in the standard, and many systems also accept 7 for Sunday. Day names like SUN and MON often work too.

How do I run a job every 15 minutes?

Use */15 * * * *. The /15 step on the minute field means "every 15th minute": at :00, :15, :30 and :45.

Why didn't my cron job run?

Common causes: a wrong path, a missing environment variable, no execute permission, the wrong timezone, or output errors you never saw because you did not log them. Add logging and test the schedule in a parser.

What timezone does cron use?

By default, the server's system timezone. On a server set to UTC, 0 0 * * * runs at midnight UTC — which may be a very different local hour for you.

The bottom line

A cron expression is just five fields — minute, hour, day-of-month, month, day-of-week — with four special characters (* , - /) to describe when a job should run. Once you can read the fields left to right, even complex schedules become obvious. Watch the day-of-month/day-of-week OR trap, mind your timezone, and always verify a new schedule with our Cron Expression Parser before you trust it in production.

P
Written by PAYATE Team

The PAYATE team builds free tools for merchants and developers.

More PAYATE tools