Cron Expressions: Reading Five Fields Without Guessing

August 19, 2026 · NOFYI Editorial Team

Backups that run at the wrong time, reports that never arrive, and surprise loads at midnight are often not bugs in your software — they’re misunderstandings of cron. When you see a five-field cron expression like 30 2 * * 1-5 copied from a Stack Overflow answer, you should know exactly what each field means, what it will and will not do on your system, and how to verify it before you trust it with a nightly backup or an hourly report.

Why five-field crons still matter

Most Unix-like systems (and many hosted Linux containers) still use the classic five-field crontab format: minute, hour, day-of-month, month, day-of-week. It’s compact and powerful, but that power comes with a few traps:

Field order — what each position means

Read cron expressions left-to-right. The five canonical fields are:

  1. Minute (0-59)
  2. Hour (0-23)
  3. Day-of-month (1-31)
  4. Month (1-12 or JAN-DEC)
  5. Day-of-week (0-7 or SUN-SAT; both 0 and 7 usually mean Sunday)

For example, 30 2 * * 1-5 means “at minute 30, hour 2, every day of month, every month, on weekdays Monday–Friday.”

Wildcards, ranges, lists, steps — the building blocks

These tokens let you compactly describe times:

Quick reference table

Field Range / Examples Common notation
Minute 0-59 */5 = 0,5,10,…
Hour 0-23 2 = 02:00
Day-of-month 1-31 1-7 = first week
Month 1-12 or JAN-DEC 6 = June
Day-of-week 0-7 or SUN-SAT 0 or 7 = Sunday

Weekday vs day-of-month — a frequent gotcha

Many users expect jobs to run only when both day-of-month and day-of-week match (logical AND), but classic Vixie-style cron treats them as an OR: if either field is restricted (not *), a job runs when either matches. That means:

Assumption note: some cron implementations or cron-like schedulers (systemd timers, Quartz, enterprise schedulers) may behave differently. Always check your system’s documentation.

Timezone surprises and DST

Cron usually uses the system’s local time. That leads to two common surprises:

Mitigations:

Missed runs and how to recover

If a machine is down during a scheduled time, classic cron will not play catch-up. Your backup that should have run at 02:00 won’t automatically run at 02:05 when the server restarts. Options to handle missed runs:

Ordered workflow: create, verify, deploy a cron for backups or reports

  1. Define the business requirement: exact hours, weekdays, tolerance for duplicates or missed runs.
  2. Write a tentative cron expression in a safe place (not directly in production crontab).
  3. Translate the expression into plain English and confirm with a colleague or the Cron Expression Explainer tool.
  4. Test on a staging system with the same timezone settings and monitor actual runs for several cycles.
  5. Deploy to production and enable logging and alerts for non-runs or duplicated runs.
  6. Include a cron-run health check script that verifies last-run timestamps and file sizes for backups.

Verification checklist (quick)

Common mistakes

Limitations and privacy considerations

Limitations:

Privacy and safety:

Concrete examples

Example 1 — nightly backup at 02:30 every day:

30 2 * * *

Meaning: at 02:30 local system time, every day of month, every month, every weekday. To avoid DST issues, you might set the server TZ to UTC and schedule 30 2 * * * in UTC.

Example 2 — generate business reports every weekday at 06:00 and every 15 minutes during business hours (09:00-17:00):

# run at 06:00 Mon-Fri
0 6 * * 1-5 /opt/reporting/run_daily_report.sh

# run every 15 minutes from 09:00 through 17:45 Mon-Fri
*/15 9-17 * * 1-5 /opt/reporting/run_quick_stats.sh

Note: If you only want the 06:00 job to run on the first weekday of the month, classic cron alone cannot express that; add a check inside the script (e.g., test for date +%d and exit if not 01).

Using Cron Expression Explainer

The Cron Expression Explainer placeholder links to a utility that parses common cron expressions and renders them as human-readable schedules. Use it to:

What it will not do:

FAQ

Q — Why did my job run twice during fall DST?

A — During DST fallback, the clock repeats one hour. If a job is scheduled inside that hour and your cron uses local time, it can run twice. Use UTC or a scheduler that avoids local-time ambiguities if duplicates are unacceptable.

Q — Can cron run a job only the last Friday of each month?

A — Not directly with a single five-field expression. A common approach is to schedule a weekly Friday job and in the script check if the date falls within the last seven days of the month (for example, check if adding seven days changes the month). Alternatively, use an external scheduler that supports advanced calendar rules.

Q — How do I prevent overlapping runs of a long job?

A — Use a lockfile or use flock to ensure only one instance runs. Example wrapper:

*/10 * * * * /usr/bin/flock -n /var/lock/myjob.lock /opt/scripts/long_backup.sh

Sources

Editorial note: This guide is an educational overview. Confirm the output against the documentation and workflow that apply to your project.