Reading a schedule before it runs in production
A cron expression is a compact schedule written as five space-separated fields — minute, hour, day of month, month, and day of week — that tells a scheduler when to run a job.
Cron syntax is dense enough that experienced engineers routinely misread it, and the failure mode is silent: the job does not error, it simply runs at a time nobody expected — or every minute of one hour instead of once an hour. The only reliable check is to look at the actual next run times.
This parser validates the expression, describes it in plain language, and lists the next ten executions in both your local timezone and UTC. This page explains each field, the four special characters, and the one rule in standard cron that surprises nearly everybody.
The five fields and their ranges
Fields are positional. A missing or extra field is the most common validation failure, because a six-field expression is valid in some other systems.
| Position | Field | Allowed values | Notes |
|---|---|---|---|
| 1 | Minute | 0–59 | |
| 2 | Hour | 0–23 | 24-hour clock; 0 is midnight. |
| 3 | Day of month | 1–31 | A value of 31 simply never fires in months that are shorter. |
| 4 | Month | 1–12 | Three-letter names such as JAN are accepted by many implementations. |
| 5 | Day of week | 0–6, with 0 = Sunday | Some systems also accept 7 for Sunday. Names such as MON are widely supported. |
Standard UNIX cron has no seconds field. If you have copied an expression with six or seven fields, it is Quartz or Spring syntax and will not validate here — drop the seconds field to convert it.
The four operators
- * — every value
- In the minute field it means every minute; in the hour field, every hour. * * * * * runs sixty times an hour.
- , — a list
- 0 9,13,17 * * * runs at 09:00, 13:00 and 17:00.
- - — a range
- 0 9 * * 1-5 runs at 09:00 on Monday through Friday.
- / — a step
- */15 * * * * runs every fifteen minutes. Steps count from the start of the range, so */7 in the minute field fires at 0, 7, 14 … 56 and then restarts — the gap across the hour boundary is four minutes, not seven.
- Timezone
- The schedule is interpreted in the timezone of the machine running it. This parser shows each run in your local timezone and in UTC so a mismatch is visible before you deploy.
- Daylight saving
- On a server using local time, a job scheduled at 02:30 can be skipped on the spring transition and run twice on the autumn one. Running servers on UTC avoids the entire class of problem.
Expressions that do not mean what they look like
Example 1: The day-of-month and day-of-week OR rule
0 0 1 * 1Runs on the 1st of every month
AND on every Monday.When both day fields are restricted, standard cron treats them as OR, not AND. To run only on a Monday that falls on the 1st, you have to check the date inside the job itself. This is the single most misread rule in cron.
Example 2: A missing minute field
* 3 * * *Runs 60 times — every minute
between 03:00 and 03:59.The intent was almost certainly 0 3 * * *, once at 03:00. This mistake usually shows up as a mysterious 60× spike in an API bill.
Example 3: A schedule that reads correctly
30 2 * * 0Every Sunday at 02:30
(shown in your timezone and UTC)Reading the next ten runs takes three seconds and catches every ambiguity above. Do it before deploying, not after the first missed window.
Operational advice cron syntax cannot express
Overlapping runs
Cron starts a new run whether or not the previous one finished. A five-minute job on a */2 schedule eventually has several copies competing. Use a lock file or your scheduler’s concurrency setting.
Everything at midnight
Scheduling every daily job at 0 0 * * * creates a load spike and makes failures interact. Spread jobs across the quiet hours and stagger the minutes.
Missed runs are not retried
If the machine is down at the scheduled moment, standard cron does not catch up when it returns. Anything that must not be skipped needs a queue with retries, not a cron entry.
A minimal environment
Cron jobs run with a very small PATH and none of your shell profile. Use absolute paths to binaries, and redirect output to a log file — otherwise failures are invisible.
Hosted schedulers differ
GitHub Actions runs schedules in UTC and may delay them under load; some managed platforms use six-field expressions or their own extensions. Validate the syntax here, then confirm against your platform’s documentation.
Alert on absence, not just on failure
A job that stops running silently is worse than one that errors. Use a dead-man’s-switch monitor that alerts when an expected check-in does not arrive.
Before adding an entry to crontab
- Read the next ten run times and confirm the first one is when you expect.
- Check the UTC column if the server is not in your timezone.
- Avoid restricting both day fields unless you genuinely want the OR behaviour.
- Redirect stdout and stderr to a log so a failure leaves evidence.
- Make the job idempotent — assume it will occasionally run twice.
- If it produces JSON output, verify the structure with the JSON formatter before wiring it into anything downstream.
How this page is maintained
The five-field format, the ten upcoming runs and the dual local/UTC display match this parser’s implementation. The day-of-month OR day-of-week rule and the absence of a seconds field reflect standard UNIX cron behaviour, which is why the page warns explicitly about six-field Quartz expressions.
Written and reviewed by the ToolsRacks editorial team. Last reviewed: .