Cron Expressions: 12 Examples Explained

When you need a task to run every night at 2 AM, back up a database every Sunday, or ping an API every five minutes, the answer in the Unix world is a cron expression explained as five small fields: 0 2 * * *. That cryptic little string is the entire schedule. Once you learn to read it — and it genuinely takes about ten minutes — you will never fear it again.

This guide teaches you to read any cron expression explained field by field, decode the special characters (*, ,, -, /, L, W, #), work through 12 real examples, and then test yourself with practice problems (answers included). It also covers the traps that copy-paste tutorials skip: the day-of-month vs. day-of-week gotcha, timezone surprises, and the fact that “cron” means slightly different things on different systems. When you are ready to build your own schedule, our free Cron Expression Generator writes the expression for you.

Table of Contents

The Five Fields: Read Any Cron Expression Explained in 10 Minutes

A standard Unix cron expression has five fields, always in this order:

minute hour day-of-month month day-of-week

Each field accepts a range of values:

  • Minute: 0–59
  • Hour: 0–23 (24-hour clock)
  • Day of month: 1–31
  • Month: 1–12 (or JAN–DEC)
  • Day of week: 0–7, where both 0 and 7 mean Sunday (or SUN–SAT)

Reading one is just substitution, left to right. Take 30 9 * * 1: minute 30, hour 9, any day of the month, any month, day-of-week 1 (Monday). So: 9:30 AM every Monday. That is all a cron expression explained really is — five slots, each narrowing down “when.”

The asterisk * means “every possible value for this field.” So * * * * * means every minute of every hour of every day — the most famous cron expression, and the one beginners paste by accident when they wanted “once a day.” (If your server suddenly runs a script 1,440 times a day, check for stray asterisks.)

Two more foundational examples before the special characters: 0 0 * * * is midnight every day (minute 0, hour 0 — “0 0” is the classic “daily at midnight” pattern), and 0 12 * * * is noon every day. Notice the pattern: the two rightmost fields stay * whenever the schedule does not care about months or weekdays.

The Special Characters, Decoded

Four operators (plus a few letters on some systems) give cron expressions their power. Learn these and you can read anything:

  • * — every value. * * * * * = every minute.
  • , — a list. 0 9,17 * * * = 9:00 AM and 5:00 PM daily. Lists let you pick specific values in one field.
  • - — a range. 0 9-17 * * * = at the top of every hour from 9 AM to 5 PM. 0 0 * * 1-5 = midnight on weekdays (Monday–Friday).
  • / — a step. */5 * * * * = every 5 minutes (minutes 0, 5, 10, … 55). 0 */2 * * * = every 2 hours. 0 9-17/2 * * * = 9 AM, 11 AM, 1 PM, 3 PM, 5 PM — range plus step combined.

On some systems (notably Quartz, used in Java scheduling, and some cloud schedulers) you get extra letters:

  • L — last. 0 0 L * * = midnight on the last day of the month (in systems that support it).
  • W — nearest weekday. 0 0 15W * * = the weekday nearest the 15th.
  • # — nth weekday. 0 0 * * 5#3 = the third Friday of the month.
  • ? — no specific value. Used in Quartz’s six/seven-field format as a placeholder in the day-of-month or day-of-week field.

Standard Unix cron (Vixie cron, the one on most Linux servers) supports only * , - /. If you see L, W, or #, you are looking at a different cron dialect — which brings us to the cross-system caveat later. Once you have had a cron expression explained operator by operator like this, the remaining mystery is mostly vocabulary, not logic.

12 Cron Expression Examples, Decoded

The fastest way to internalize a cron expression explained is to read a dozen of them. Cover the right column, decode the left, then check yourself:

  1. */5 * * * * — every 5 minutes
  2. 0 * * * * — at the top of every hour
  3. 0 2 * * * — 2:00 AM every day
  4. 30 9 * * 1-5 — 9:30 AM, Monday to Friday
  5. 0 0 * * 0 — midnight every Sunday
  6. 0 8 1 * * — 8:00 AM on the 1st of every month
  7. 15 14 1 * * — 2:15 PM on the 1st of every month
  8. 0 22 * * 1,3,5 — 10:00 PM every Monday, Wednesday, and Friday
  9. */15 9-17 * * 1-5 — every 15 minutes between 9 AM and 5 PM on weekdays
  10. 0 0 1 1 * — midnight on January 1st (once a year)
  11. 0 6 * * 6,0 — 6:00 AM every Saturday and Sunday
  12. 45 23 * * * — 11:45 PM every day

Two to study closely. Number 9 combines everything: a step (*/15), a range (9-17), wildcards, and a weekday range (1-5). Number 6 vs. 7 shows the classic month-day pattern: 0 8 1 * * pins the day-of-month to 1 while month stays wild — “the first of every month.” Reading a dozen schedules like these is the fastest way to get a cron expression explained in a way that sticks, because patterns beat memorization.

The Three Traps Everyone Falls Into

Trap 1: day-of-month AND day-of-week is really OR

This is the single most common cron bug. Write 0 0 1 * 1 expecting “midnight on the 1st, but only if it’s a Monday” — and cron runs it on the 1st of the month and every Monday. When both day fields are restricted (not *), standard cron treats them as OR, not AND. There is no clean way to express “the 1st AND a Monday” in classic five-field cron; you need a wrapper script that checks the date, or a scheduler with richer syntax.

Trap 2: timezones

Cron runs in the system timezone, not yours. A server in UTC running 0 2 * * * fires at 2 AM UTC — which is 7 AM in Karachi in winter (PKT is UTC+5) and 6 AM in summer daylight zones elsewhere. After any server migration or daylight-saving change, re-verify. The number of “my job ran an hour early” incidents caused by DST would fill a book.

Trap 3: no seconds, and “every 90 seconds” is impossible

Standard cron’s finest grain is one minute. You cannot express “every 30 seconds” or “every 90 seconds” in a five-field expression — */0.5 is not valid. The workaround is running the job every minute and handling sub-minute timing inside your script, or using a scheduler with a seconds field (Quartz and most cloud schedulers have one).

Practice: Decode These Yourself (Answers Below)

Read each cron expression explained in plain English before scrolling to the answers. No peeking.

  1. 0 7 * * *
  2. */10 * * * *
  3. 0 18 * * 5
  4. 30 6 15 * *
  5. 0 */4 * * *
  6. 0 9 * * 1-5 (trick: compare with example 4 above)

Answers: (1) 7:00 AM every day. (2) Every 10 minutes. (3) 6:00 PM every Friday. (4) 6:30 AM on the 15th of every month. (5) Every 4 hours, at minute 0 (12:00 AM, 4:00 AM, 8:00 AM…). (6) 9:00 AM Monday–Friday — same pattern as “30 9 * * 1-5” but at minute 0 instead of 30. If you got 5 of 6, you can read cron.

The Honest Cross-System Caveat

Here is what copy-paste tutorials never tell you: “cron expression” is not one universal language. Standard Unix cron uses five fields. Quartz (Java) uses six or seven, starting with seconds: 0 0 12 * * ? means noon daily in Quartz — paste that into Unix cron and it is garbage. GitHub Actions uses five fields like Unix but with its own quirks (minimum interval of 5 minutes, schedules run on UTC). AWS EventBridge, Kubernetes CronJobs, and WordPress’s WP-Cron each have their own dialect and limitations.

The practical rule: always check which scheduler will run your expression, and test with a harmless command first (have it append a timestamp to a log file). A cron expression explained for Unix cron is not automatically valid in Quartz or GitHub Actions — the dialect check comes before the syntax check. An expression that is perfectly valid in one system can be silently wrong — or loudly error — in another. Our Cron Expression Generator targets the standard five-field Unix format; if your platform uses seconds-first syntax, say so in its notes field when you copy the result across.

Try It: Cron Expression Generator

Reading cron is a skill; writing it from scratch every time is a chore. Now that you have had a cron expression explained from fields to traps, generating your own schedules is the easy part. Our free Cron Expression Generator lets you pick “every 5 minutes,” “weekdays at 9:30 AM,” or any custom pattern and produces the correct five-field expression instantly — no memorization required. Pair it with a Unix timestamp converter when you are debugging “when exactly did that job fire,” and consult the Wikipedia article on cron for the full history of the scheduler that has been running the world’s background jobs since 1975.

Frequently Asked Questions

What does * * * * * mean in cron?

Every minute of every hour of every day — the expression runs 1,440 times daily. Each asterisk means “every possible value” for its field (minute, hour, day of month, month, day of week). It is the most commonly pasted cron expression and the most common accident: beginners often intend “once a day” (0 0 * * *) and get “every minute” instead.

How do I run a cron job every 5 minutes?

Use */5 * * * * — the */5 in the minute field means “every 5th minute” (minutes 0, 5, 10, up to 55). This is the canonical cron expression explained for sub-hourly intervals. For every 10, 15, or 30 minutes, swap in */10, */15, or */30.

What is the difference between cron and crontab?

Cron is the background service (daemon) that runs scheduled tasks; crontab is the command and file format used to define those tasks. You write cron expressions into your crontab (crontab -e to edit), and the cron daemon reads the crontab and executes commands on schedule.

Why did my cron job run twice / on the wrong day?

The usual suspects: both day-of-month and day-of-week were restricted (cron treats them as OR, not AND), the server timezone differs from yours, or daylight saving shifted the schedule. Check the expression field by field, confirm the system timezone with the date command, and remember there is no seconds field in standard cron.