Wernzi Tools Guide
Cron Expressions Explained
Cron expressions schedule recurring jobs with five fields for minute, hour, day, month and weekday. Learn the syntax, shortcuts and common mistakes.
Every night at 2 a.m., a backup runs. Every Monday morning, a report goes out. Every hour, a cache clears. Behind almost all of this is a cron expression — a compact five-field string that describes when a job should repeat. Cron has scheduled work on Unix systems since the 1970s, and today the same syntax powers GitHub Actions, cloud schedulers and countless apps.
Cron expressions look cryptic at first — "0 2 * * 1" means something precise — but they are built from a few simple patterns. This guide teaches you to read and write them confidently.
The five fields
A standard cron expression has five fields, separated by spaces, read left to right: minute, hour, day of month, month, and day of week. Each field accepts a range of values: minutes 0–59, hours 0–23, days of month 1–31, months 1–12, and weekdays 0–7, where both 0 and 7 mean Sunday.
The asterisk (*) is a wildcard meaning "every". So "* * * * *" runs every minute, "0 * * * *" runs at the top of every hour, and "0 0 * * *" runs once a day at midnight. A single value pins the field: "30 9 * * *" runs at 9:30 every morning.
┌── minute (0-59)
│ ┌── hour (0-23)
│ │ ┌── day of month (1-31)
│ │ │ ┌── month (1-12)
│ │ │ │ ┌── day of week (0-7, 0 and 7 are Sunday)
│ │ │ │ │
* * * * *
0 2 * * 1 -> 02:00 every MondayLists, ranges and steps
Commas build lists: "0 9,17 * * *" runs at 9:00 and 17:00. Hyphens build ranges: "0 9-17 * * *" runs at the top of every hour from 9 through 17. A slash adds a step: "*/15 * * * *" runs every 15 minutes, and "0 9-17/2 * * *" runs at 9, 11, 13, 15 and 17.
Combining these, you can express almost any regular schedule in a few characters. "30 4 1 * *" is the first of the month at 4:30. "0 0 * * 0" is midnight on Sunday. "0 12 15 * *" is noon on the 15th of every month. Read each field independently and the expression decodes itself.
Day of month vs day of week
The one genuine trap in cron is that the day-of-month and day-of-week fields combine with OR, not AND, when both are restricted. The expression "0 0 1 * 1" does not mean "the first of the month if it is a Monday" — it means "midnight on the 1st of the month OR on any Monday". This surprises almost everyone the first time they meet it.
If you need both conditions to hold, use a single field and check the other condition inside the job itself, or use a scheduler that supports the combination explicitly. When in doubt, paste the expression into a cron parser and inspect the next few run dates — it shows exactly what the schedule will do.
Shortcuts and special strings
Many cron implementations support friendly shortcuts. @hourly means "0 * * * *", @daily (or @midnight) means "0 0 * * *", @weekly means "0 0 * * 0", @monthly means "0 0 1 * *", @yearly (or @annually) means "0 0 1 1 *", and @reboot runs once when the system starts. These are easier to read than the numeric form and mean exactly the same thing.
Some systems add a sixth field for seconds at the front, or named months and weekdays ("JAN", "MON"). Check your scheduler's documentation — the five-field form is the portable core, and extensions vary between implementations.
- @hourly — at the start of every hour
- @daily — once a day at midnight
- @weekly — once a week, Sunday midnight
- @monthly — once a month, on the 1st at midnight
- @yearly — once a year, January 1st at midnight
- @reboot — once, when the system starts
Testing a schedule before you trust it
A wrong cron schedule fails silently — the job simply runs at the wrong time, or never. Before deploying a schedule, verify it with a cron parser: enter the expression and read the next ten run times. If the next runs are not what you expect, adjust before it matters. Pay special attention to time zones: cron runs in the server's local time unless your scheduler says otherwise, and daylight saving changes can shift or skip runs.
For important jobs, add monitoring that alerts you if a run is missed. And keep the schedule next to the job definition in version control, so a change to either is reviewed together.
Five everyday schedules, decoded
Read each expression field by field and it decodes itself: minute, hour, day of month, month, weekday. If a schedule looks wrong, check the weekday field first — it is the one most people misread, because 0 and 7 both mean Sunday and the numbering starts at Sunday, not Monday.
- 0 9 * * 1-5 — 9:00 on weekdays. The classic start-of-workday job.
- 0 2 * * 0 — 2:00 every Sunday. A weekly backup in the quiet hours.
- */10 * * * * — every 10 minutes. A health check or queue poller.
- 0 0 1 * * — midnight on the 1st. Monthly invoicing or cleanup.
- 30 18 * * 5 — 18:30 every Friday. The end-of-week report.
Common cron mistakes
Four mistakes cause most cron trouble. Forgetting the time zone — cron runs in the server's local time, so a job scheduled for 2:00 runs at a different UTC time after a daylight saving change. Scheduling two heavy jobs at the same minute, so they compete for resources. Assuming a job that runs long will not overlap with its next run — cron starts a new instance regardless. And never monitoring: a failed job that fails silently can go unnoticed for weeks.
Try it yourself
Put what you just read into practice with these free tools — no sign-up needed.
Keep learning
- What Is JSON and How to Format It — 6 min read
- How to Generate a Strong Password — 6 min read
- Base64 Encoding Explained — 5 min read