A standard five-field cron expression describes when a scheduler should trigger a task: minute, hour, day of month, month, and day of week. For example, */5 * * * * matches every five-minute mark, while 0 9 * * 1-5 matches 09:00 Monday through Friday under the traditional Unix cron interpretation.
Those expressions are not universally portable. Cron implementations differ in supported fields, weekday numbering, timezone configuration, and how they interpret edge cases. Identify the scheduler first, then validate the expression against that scheduler's documentation.
The five fields in a cron expression
In traditional Unix crontab, the five time fields appear in this order:

The five time fields in a traditional Unix cron expression
| Field | Common range | Example meaning |
|---|---|---|
| Minute | 0–59 | 15 means at minute 15 |
| Hour | 0–23 | 9 means 9 AM |
| Day of month | 1–31 | 1 means the first calendar day |
| Month | 1–12 | 6 means June |
| Day of week | 0–7 in Linux cron | 1 means Monday; 0 or 7 means Sunday |
The command or workflow configuration comes after the time fields in a crontab entry. A cron expression copied into a framework configuration may be parsed differently, so do not assume every field range or extension is identical. The Linux crontab(5) manual documents the traditional five-field layout and Linux cron's day-of-week convention.
The main cron operators
Common five-field cron formats use these operators:
- * — every allowed value in that field.
- , — a list of specific values, such as 1,15.
- - — an inclusive range, such as 1-5.
- / — a step within a field, such as */5 for every fifth minute value.
Examples below use the traditional five-field Unix cron format. Their descriptions are expected interpretations of the expressions, not observations from a running scheduler.
| Expression | Expected interpretation |
|---|---|
| * * * * * | Every minute |
| */5 * * * * | Every five minutes, at minute values 0, 5, 10, and so on |
| 0 * * * * | At the start of every hour |
| 0 9 * * 1-5 | At 09:00 Monday through Friday |
| 0 0 1 * * | At midnight on the first day of each month |
| 30 8 * * 0 | At 08:30 every Sunday in Linux cron, where 0 means Sunday |
A step is evaluated within its field's range. For example, */5 in the minute field means the minute values divisible by five. It does not mean “wait five minutes after this job finishes,” and it does not create a durable interval measured from the time the job was installed.
How to read an expression from left to right
Take this expression:
15 6 * * 1-5
Read each field in order:
- 15 — minute 15.
- 6 — hour 6, using a 24-hour clock.
- * — every day of the month.
- * — every month.
- 1-5 — Monday through Friday in the traditional Linux cron convention.
The expected interpretation is 06:15 on weekdays, in the timezone used by the scheduler. The expression itself does not contain a timezone.
The day-of-month and day-of-week rule
One of the easiest mistakes is restricting both the day-of-month and day-of-week fields and assuming they form an AND condition.
In the traditional Linux cron behavior documented by crontab(5), when both fields are restricted (neither is *), a job runs when either field matches. For example:
0 9 1 * 1
This is expected to match 09:00 on the first day of each month and 09:00 on Mondays, not only Mondays that fall on the first. This rule is implementation-specific; check the target scheduler before transferring the expression elsewhere.
If you intend “the first day of the month, only when it is Monday,” traditional cron's five fields do not express that AND condition directly. Use a scheduler with suitable calendar rules or make the additional condition explicit in the job itself.
Weekday numbering is not universal
Do not copy weekday numbers between schedulers without checking the target's convention. The Linux crontab(5) manual accepts 0 or 7 for Sunday and 1–6 for Monday through Saturday. GitHub Actions documents its own five-field schedule syntax with weekday values 0–6, where Sunday is 0. Workflow syntax for GitHub Actions
Names such as MON or JAN, a seconds field, and special tokens such as ? or L are not part of the portable five-field baseline. Some schedulers support extensions; others reject them or interpret them differently. Use the scheduler's primary documentation as the authority for its accepted syntax.
Time zones and daylight-saving time
A cron expression specifies calendar fields, not a timezone. The effective timezone comes from the scheduler or its configuration. A schedule intended for 09:00 local time may therefore run at a different local hour if the scheduler evaluates it in UTC or another zone.
Daylight-saving transitions are also scheduler-specific. The Linux crontab(5) manual notes that nonexistent local times during a spring-forward transition do not match, while repeated times during a fall-back transition can run twice. Other platforms may use different rules. If a task must run once per business day, avoid assuming that the same expression guarantees identical behavior across every DST transition.
For a production schedule, confirm all three items:
- Which timezone the scheduler actually uses.
- How that scheduler handles skipped or repeated local times.
- Whether a delayed, skipped, or duplicate trigger is acceptable for the task.
A scheduled trigger is not a guarantee that the work will start exactly on time or finish successfully. The scheduler, host, queue, and job implementation all affect execution and recovery.
Build and check an expression
Start with the intended schedule in plain language—for example, “every weekday at 09:00 in the scheduler's configured timezone.” Translate that requirement into the target scheduler's dialect, then check the expression and its expected calendar matches before deploying it.
The Letinix Cron Expression Builder is the relevant utility when you want to construct or inspect an expression directly. Check its current format and preview assumptions against the scheduler you are configuring; a builder does not replace the scheduler's own validation or documentation.
A short validation checklist
Before saving a cron schedule, verify:
- The target expects five fields rather than a six-field format with seconds.
- Each field uses the target's accepted range and operators.
- Weekday numbering matches the target scheduler.
- Restricted day-of-month and day-of-week fields have the intended combined behavior.
- The scheduler's timezone and daylight-saving behavior match the requirement.
- The job is safe if it starts late, is skipped, runs twice, overlaps a previous run, or fails after being triggered.
For Linux-specific behavior, use the Linux crontab(5) manual. For GitHub Actions, use the official workflow syntax reference and events that trigger workflows. Other platforms should be checked against their own scheduler documentation.
References
crontab(5) — Linux manual page
Workflow syntax for GitHub Actions — GitHub Docs
Events that trigger workflows — GitHub Docs
This article was originally published on Letinix.
Top comments (1)
Good point that cron expressions aren't portable between schedulers. One habit that helps is writing the intended time in plain words next to each expression, plus the timezone the scheduler uses, so the next person can check it quickly.