Cron Expression Builder

Cron Expression Builder

Build cron expressions visually with schedule preview. Validate crontab syntax for Linux, Kubernetes, AWS. Free online cron job generator

Cron expressions look simple but trip up almost everyone. "Every Monday at 3am" is 0 3 * * 1, not 0 3 * * 0 — Sunday is 0 in standard cron but 7 in some dialects. Day-of-month and day-of-week are OR-ed, not AND-ed: 0 0 13 * 5 fires on every 13th AND every Friday. This builder picks fields visually, previews the next ten fire times in your timezone, and warns you about the gotchas.

The five fields

Standard cron has five space-separated fields. From left to right:

  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–6 where 0 = Sunday, or SUN–SAT — and some dialects also accept 7 = Sunday)

Each field accepts: a number (5), a range (1-5), a step (*/15), a list (1,3,5), or wildcards (*). Combined: 0 9-17/2 * * MON-FRI runs every 2 hours during business hours on weekdays.

The big gotcha: day-of-month vs day-of-week

When BOTH the day-of-month and day-of-week fields are restricted (neither is *), they are OR-ed together, not AND-ed. This is counterintuitive and the source of most "why is my cron running every Friday" surprises.

Input

0 0 13 * 5

Output

Reading: minute=0, hour=0, day-of-month=13, any-month, day-of-week=Friday

Fires on:
  - Every 13th of the month at midnight (regardless of weekday)
  - Every Friday at midnight (regardless of date)

NOT just "Friday the 13th". For that, you need application logic or a calendar-aware scheduler.

To fire ONLY on a specific weekday AND date, use one of the fields restricted and check the other in your job. POSIX cron has no way to AND these two fields together.

Dialect differences

  • POSIX/Linux cron — 5 fields, day-of-week 0-6 (Sunday=0), no second field, no "L" (last), no "W" (weekday). Used by /etc/crontab, anacron, most container schedulers.
  • Quartz (Java) — 6 or 7 fields (adds seconds at the front, optional year at the end). Supports L (last), W (nearest weekday), # (nth occurrence of weekday). Used by Spring @Scheduled, Quartz framework.
  • Kubernetes CronJob — 5 fields, POSIX-compatible. Sunday=0. Wraps standard cron.
  • AWS EventBridge — 6 fields, requires either day-of-month OR day-of-week to be ?, never both *. Sunday=1.
  • Vixie cron extensions — @hourly, @daily, @weekly, @monthly, @yearly, @reboot. Convenient but non-portable.

Copy-pasting an expression between dialects often produces a syntactically-valid expression that fires at the wrong time. Always double-check against your specific scheduler's documentation.

When to reach for this tool

  • You wrote "every 15 minutes" but want to verify the cron actually fires at :00, :15, :30, :45 and not some weird offset.
  • You inherited a crontab entry and need to understand what it does without running it for a month to find out.
  • You are debugging "the job runs on Sunday but the user expected Monday" — different dialects, different Sunday-numbering, you need to see the resolved schedule.
  • You are setting up a backup window during off-hours and want to make sure it does not collide with the daily report job (paste both, compare next-fires).

What this tool will not do

  • It will not execute your job. The preview shows when an entry would fire, not what would happen. Test the actual command in a staging environment.
  • It will not handle timezone DST gracefully across all dialects. POSIX cron generally uses the system timezone and may fire twice or zero times across DST transitions depending on local rules. For DST-safe scheduling, use a scheduler with explicit UTC semantics (e.g. Quartz with timeZone set, or systemd timers).
  • It will not check whether the underlying job overlaps with itself if it takes longer than the interval. That is the scheduler's problem — most cron implementations will happily start a second copy before the first finishes.

Frequently asked questions

Why does my "every 5 minutes" cron sometimes skip a minute?

Standard cron fires at exact minute boundaries based on the system clock. If your job takes 6 minutes, the next "scheduled" run is skipped because cron does not queue overlapping starts (in some implementations). Use a job runner that supports overlap policies, or shorten the job.

What does the "@reboot" line do in crontab?

Runs the command once when the cron daemon starts (typically at system boot). Useful for legacy "run at startup" tasks, but on modern systemd-based Linux, prefer a systemd service or oneshot unit — it gives better dependency management and log handling.

How do I run a cron job every weekday except holidays?

Cron cannot do this directly. Either run every weekday and have the job itself check a holiday calendar, or use a scheduler with calendar support (Airflow, Prefect, AWS EventBridge with input transformer + Lambda).

Is 0 0 * * * the same as @daily?

Yes, in POSIX cron and most implementations. @daily is the equivalent of 0 0 * * * (midnight every day). @hourly = 0 * * * *. @weekly = 0 0 * * 0. @monthly = 0 0 1 * *. @yearly = 0 0 1 1 *.

Does cron run in UTC or local time?

Depends on the system. /etc/crontab usually uses the system timezone (TZ env variable). Per-user crontabs respect TZ if set. Cloud schedulers (EventBridge, Kubernetes) typically use UTC unless configured otherwise. Always confirm before relying on it.

Can I trigger a cron job at "the first Monday of the month"?

Not in POSIX cron — only in Quartz with the # operator: 0 0 ? * MON#1. In POSIX cron you can approximate by running every Monday and checking inside the job whether day-of-month is 1-7.

Related tools

Last updated · E-Utils editorial team