Cron Expression Parser & Next-Run Preview

Translate any cron expression into plain English and see the next 5 run times.

ZERO UPLOAD · ALL LOCAL

What this page covers

  • 6-field format minute hour day-of-month month day-of-week year, wrapped in cron(...)
  • Required ? placeholder day-of-month or day-of-week must be ?; both cannot be set to concrete values
  • Day-of-week numbering EventBridge uses Sunday = 1, unlike standard Unix cron's Sunday = 0
  • L and # operators supported in EventBridge (6L = last Saturday, 2#1 = first Monday) but not in standard 5-field cron

What this page covers

  • Calendar expression shape [DayOfWeek] [Year-Month-Day] [Hour:Minute:Second], distinct from 5-field cron syntax
  • Shorthand aliases daily, hourly, weekly, monthly expand to their full calendar-expression equivalents
  • Persistent=true backfills a missed run after downtime; not the default behavior
  • AccuracySec defaults to 1 minute of firing slack; set to 1s to force near-exact timing at the cost of wake-up batching

What to look for

  • minutes 1, 5, 6, 7, 8, 9, 10, 15
  • Monday, Wednesday, Friday

What to look for

  • fires at 10, 20, 30, 40, 50
  • equivalent to 0,5,10,...,55

What to look for

  • /usr/bin:/bin

What to look for

  • lists the current crontab, back this up before -r or -e
  • deletes the entire crontab immediately, no confirmation

What to look for

  • */15 * * * *
  • 0 9 * * 1-5
  • 0 0 1 * *

What to look for

  • once per minute (* * * * *)

What to look for

  • /var/spool/cron/crontabs/username
  • /var/cron/tabs/username

What to look for

  • 5 fields
  • 6 fields, adds year
  • 6 to 7 fields, prepends seconds

What to look for

  • once per minute, a hard boundary not a tunable parameter
  • /var/spool/cron/crontabs/
  • /etc/crontab and /etc/cron.d/
  • systemctl status cron (Debian/Ubuntu) or systemctl status crond (Fedora/RHEL/CentOS)

Prefer systemctl reload cron for routine crontab edits; a restart terminates in-flight jobs before reloading.

What to look for

  • 0 0 * * *
  • 0 0 * * 0
  • 0 0 1 1 *

What to look for

  • matches all values, e.g. 0-59 in the minute field
  • fires at 0, 5, 10, ..., 55

What to look for

  • 0 (or 7)
  • 1
PRESETS

MIN
HR
DOM
MON
DOW

Output (Parsed schedule)

SCHEDULE

NEXT 5 RUNS
    1. Type or paste a 5-field cron expression into the input (e.g. */15 * * * *).
    2. Use the preset buttons to load a common schedule instantly.
    3. Edit individual fields (MIN, HR, DOM, MON, DOW) — the expression updates live.
    4. Read the SCHEDULE panel for a plain-English description of the pattern.
    5. Choose a timezone and clock format, then read NEXT 5 RUNS for upcoming execution times.

    What is a cron job?

    Cron is a background scheduler on Unix-like systems, and a cron job is one command plus the schedule that fires it. The daemon wakes every minute, examines every registered job, and runs those whose schedule matches the current time,1 which is why cron expressions describe minutes rather than durations: the daemon does not count elapsed time, it matches wall-clock fields against the current minute. Nothing about a cron job is continuous; each firing is a fresh process spawned at a moment the expression selected. That model is simple, robust, and easy to reason about once you can read the five fields.

    Each user's jobs live in their own crontab, a per-user file where every line pairs a schedule expression with the command to run. The schedule is the machine-readable half of the line and the command is what actually executes, so a crontab reads as a list of when-then pairs. You edit yours with crontab -e and list it with crontab -l,2 and the daemon picks up the change without a restart.3 The command half can be anything the shell can run, from a one-line log cleanup to a full deployment script, and it runs with your account's permissions.4

    This tool touches only the schedule half of the line. The parser validates the expression, translates it into plain English, and previews the runs it selects; the command half never enters this page, because a valid schedule here says nothing about whether the command will succeed when the daemon fires it. A job that is scheduled correctly but failing in production has a runtime problem, not a syntax problem, and the debugging section later in this article picks that side up. Preview the schedule here, then trust the daemon's own logs to tell you what happened when it fired.

    The 5 cron fields

    Every cron expression is a string of five fields separated by whitespace, and each field controls one dimension of the schedule. Reading them in order from left to right gives you minute, hour, day-of-month, month, and day-of-week, with an optional year field added by some implementations. Understanding what each field accepts and how the fields interact is the first step toward writing schedules that behave predictably in production.

    Cron parser with the expression 0 9 * * 1-5 split into its five fields and the next five run times listed in UTC
    0 9 * * 1-5 reads as "At 09:00 AM, Monday through Friday". Checked on Monday 5 October 2026 after 09:00 UTC, the next runs fall on 6, 7, 8, 9 and 12 October at 09:00 UTC, skipping the weekend.

    The five fields are fixed in order, and changing the value of one field never shifts the meaning of the others. That independence is what makes cron composable: you can change the hour without touching the minute, or restrict the day-of-month without affecting the day-of-week. The trade-off is that a single misplaced character in any field can change the schedule in ways that are hard to spot without a preview, which is exactly the kind of mistake this tool is designed to catch.

    Field order and accepted values

    A standard Unix cron expression has five space-separated fields: minute (0–59), hour (0–23), day-of-month (1–31), month (1–12), and day-of-week (0–7, where both 0 and 7 represent Sunday). Each field accepts a specific value, a wildcard * (every valid value), a range 1-5, a list 1,3,5, or a step */15. You can also use names in place of numbers for the month and day-of-week fields, such as mon,wed,fri or jan-mar.5

    Using steps and lists

    Steps are the most compact way to express recurring intervals. */15 in the minute field runs at minutes 0, 15, 30, and 45, while 0-23/2 in the hour field runs every other hour. Lists let you pick several specific values at once, so 1,15 in the day-of-month field fires on the first and fifteenth. The tool translates each combination into plain English so you can verify intent before deploying.4

    You can also combine a range with a step, as in 1-30/5, which fires on the 1st, 6th, 11th, 16th, 21st, and 26th of the month. Mixing these syntaxes across the five fields is what makes cron powerful but also easy to get wrong, which is exactly why a plain-English preview is worth checking before you save a new line.

    Special @-shortcuts

    Many cron implementations support @-prefixed shortcuts as readable aliases for common schedules. @hourly is equivalent to 0 * * * *; @daily to 0 0 * * *; @weekly to 0 0 * * 0; @monthly to 0 0 1 * *; and @yearly (or @annually) to 0 0 1 1 *. The special @reboot shortcut runs the job once when the system starts.6

    NOTE Quartz scheduler adds non-standard extensions such as L (last day), W (nearest weekday), and an optional 6th seconds field before the year. Systemd timers go further with calendar specifications and timezone names. This tool parses standard Unix cron, including the optional leading seconds field, while Quartz-specific operators such as L and W, the year extensions, and systemd calendar specifications fail to parse here.78

    Cron dialects across platforms

    The five-field shape carries across modern scheduling platforms, from CI pipelines to container schedulers to serverless cron triggers, and each platform implements a dialect of it. Some prepend a seconds field to the familiar five; some number the days of the week differently; some reject month and day names; some enforce minimum intervals between runs; and one platform's wildcard can mean something another's does not. The core idea transfers, the details do not. Reading any platform's schedule field documentation is the only way to know which dialect you are writing.

    This parser speaks the standard Unix dialect, verified against the five shared fields. When a platform's schedule misbehaves, read the platform's own schedule-field documentation first to learn its dialect, then confirm the five shared fields here; dialect-specific syntax is the platform's to document, and this page never claims to validate any platform's variant. Treating a platform's expression as standard Unix cron is the mistake the dialect map above exists to prevent. A next-runs preview is only as trustworthy as the dialect it was parsed in.

    Timezones and your server

    Cron expressions describe when a job should run, but the clock that evaluates them lives on the server that hosts the cron daemon. When your development machine, your production server, and your users span multiple timezones, the same expression can produce different wall-clock results depending on where it is executed. The tool surfaces this offset explicitly so you can reason about it rather than discover it after a missed run.

    Server local time and UTC

    Cron daemons use the local clock of the machine they run on, with no built-in timezone conversion of their own. If your server is in UTC and you schedule 0 9 * * * expecting a 9 AM job, it fires at 9 AM UTC rather than 9 AM in your local timezone. The tool previews run times using your browser's timezone, which may differ from your server's, and the timezone label shown in the preview makes that offset visible so you can reconcile the two clocks.6

    Daylight saving transitions

    Daylight saving transitions add another wrinkle for any time-based scheduler. When clocks spring forward, jobs that would have run during the skipped hour are typically executed immediately; when clocks fall back, the system avoids running the same job twice. The exact behaviour depends on your operating system and cron implementation. For jobs where exact local timing matters, consider using a timezone-aware scheduler such as systemd timers with OnCalendar, or a cron wrapper that handles DST transitions explicitly.3

    Common schedule patterns

    While cron syntax can express almost any schedule you can think of, a handful of patterns cover the vast majority of real-world jobs. Recognising these idioms makes it easier to read unfamiliar crontabs and gives you a head start when writing new ones. The examples below are the ones you will reach for most often, whether you are polling a queue, rotating logs, or running a monthly billing job.

    Patterns for common intervals

    A small set of expressions covers the majority of real-world scheduling needs. */5 * * * * runs every 5 minutes, which is a common polling interval for health checks and queue workers. 0 3 * * * runs nightly at 3 AM, a typical window for database backups and log rotation. 0 9 * * 1-5 runs at 9 AM on weekdays only, and 0 0 1 * * runs at midnight on the first of every month, which suits billing jobs and monthly reports.

    Preview before deploying

    When writing a new expression, enter it in the tool above to confirm the English description matches your intent, then check that the next 5 run times fall on the dates and hours you expect. Subtle syntax errors, such as a , where a - belongs inside a range, produce expressions that are still valid but schedule the wrong moments, and these mistakes are easy to miss without a preview. Always paste a new production cron line through the parser once before relying on it.

    Avoiding common scheduling mistakes

    Most cron surprises come not from obscure syntax features but from the way standard fields interact when you combine them in ways that feel intuitive. Day-of-month and day-of-week are the classic pair: specifying both produces a union rather than an intersection, and that behaviour catches out anyone expecting the job to fire only when both conditions line up. Once you understand these edge cases, you can lean on the tool's preview to confirm the schedule before it goes live.

    How day-of-month and day-of-week interact

    Day-of-month and day-of-week fields interact in a way that surprises many developers. In standard Unix cron, when you specify both a day-of-month value and a day-of-week value (neither is a wildcard asterisk), most implementations fire the job on days matching either condition, not only days that satisfy both. The expression 0 9 1 * 1 runs at 9 AM on the first of every month and at 9 AM every Monday, not only on Mondays that fall on the first. The plain-English description this tool generates makes the actual interpreted schedule visible before you deploy, so there are no surprises in production.5

    Monthly jobs and the last-day gap

    Monthly jobs that target a specific day face a reliability gap. The expression 0 0 31 * * silently skips February, April, June, September, and November, because those months have fewer than 31 days and the cron day-of-month field has no notion of the last day. Checking the Next 5 Runs preview for a monthly expression reveals exactly which calendar dates will fire and quickly exposes this kind of gap. When you need a job to run on the last calendar day of every month, the standard approach is a wrapper script that checks whether tomorrow is the first of the next month, rather than relying on a raw cron expression that cannot express the concept directly.

    When the schedule is right but the job still fails

    Two runtime surprises account for most of the rest. First, cron jobs run with a minimal environment: the daemon sets only a handful of variables, such as the shell and home directory, rather than the full set an interactive shell provides, so a command that works in your terminal can fail from cron.2 Second, anything the job prints is mailed to the crontab's owner rather than shown on any terminal,1 so a job with no visible output is usually a job whose output nobody read. Redirecting each line's output and errors to a log file turns invisible failures into readable ones, which is the habit worth forming before you need it.

    The debugging order matters. Read the daemon's log first to confirm the job fired at all; then capture the job's own output to see the real error; only then bring the expression back here to rule the schedule in or out. This parser validates the schedule and never the execution environment, so it is step one of a cron debugging loop, not the whole loop. Most jobs that "never ran" did run: the schedule fired, the command failed, and the evidence went to a mailbox nobody checks.

    Valid Cron Expression Checklist

    • Exactly 5 space-separated fields Minute, hour, day-of-month, month, and day-of-week in that order make the standard dialect; an optional leading seconds field also parses, and Quartz operators are the part that fails.
    • Steps, ranges, and lists used correctly */15 for every 15 units, 1-5 for a range, 1,3,5 for a list — mixing the wrong syntax in a field is the most common paste error.
    • Day-of-month and day-of-week not both restricted unintentionally Restricting both fields at once fires on either match, not the intersection, which surprises most people the first time.
    • Plain-English description matches your intent Read the SCHEDULE panel and Next 5 Runs before deploying — they catch subtle field-order mistakes a glance at raw syntax misses.

    Paste your own expression above and check its plain-English description and next runs against this list.

    Checking Crontab Syntax Before You Deploy

    Most scheduling mistakes start as a line the cron daemon accepted without complaint, so the cheapest fix is to check every expression before it reaches a server. The guide below lists the syntax errors that slip through, the ways to validate a line in your shell and in CI, the edge cases that pass a syntax check but still run at the wrong time, and the logic errors that only the next run times reveal.

    A cron line can look correct and still be wrong. A misconfigured expression is silently accepted and either runs at the wrong time or never runs at all.1 Checking syntax before deployment is the only reliable way to catch errors; an out-of-range value (like 60 in the minute field) or a misplaced operator (*/0 as a step) will not warn you, and the daemon simply ignores or misinterprets the line.2

    Choosing the right validation tool

    The fastest check is a browser-based parser like this one: paste the expression and read the English description or the next 5 run times. If the description says something different from your intent, the expression is wrong before any code is deployed. More thorough checks involve running the expression through a shell command on the target system or using the systemd-analyze calendar command as a cross-reference.

    Common crontab syntax errors

    The most frequent mistakes are: using 60 in the minute field (valid range 0 to 59), using 24 in the hour field (valid range 0 to 23), a step of 0 like */0 (undefined behavior), combining both day-of-month and day-of-week as non-wildcards expecting AND behavior (cron uses OR), and missing a space between fields causing the parser to misread the expression entirely.

    Reading the parser result before editing the crontab

    Do not stop at a green syntax check. Read the plain-English description and compare the next several run times with the schedule you intended. This catches logic mistakes that are technically valid, such as a weekday rule that fires more often than expected or a step expression that skips the target hour. Pay special attention to expressions that combine day-of-month with day-of-week, since the OR behavior between those two fields is the single most common source of unintended trigger frequency.

    Treat the parser as a translation step, not a rubber stamp, because a green check only proves the fields parse rather than that the schedule matches your intent. The next several trigger times are the real test: skim them for the cadence, weekday, and month pattern you expected, and only then paste the expression into the crontab. This two-step habit turns a silent misconfiguration into a visible one before the job is live.

    Practical syntax validation techniques

    Browser parsers give instant feedback on expression structure and show the next trigger times, which makes them the fastest way to confirm an expression is well-formed before you deploy it to a live server. crontab -l on Linux lists the current crontab but does not validate syntax; it prints the file as-is.

    Choosing a programmatic validator

    Consequently, croniter (Python) or cron-parser (Node.js) are the best programmatic validators: both parse expressions and can enumerate the next N trigger times without running any system cron daemon. For CI pipelines that already run Node.js tests, cron-parser integrates with a single require() call and throws a descriptive error on malformed input,3 making it the fastest path from pull request to validated schedule. Python projects benefit from croniter in the same way, with croniter.is_valid() returning a boolean that fits cleanly into existing test assertions.4

    Edge cases that pass syntax checks but behave unexpectedly

    0 0 29 2 * runs on February 29 (valid, but fires only in leap years). 0 0 31 * * fires on the 31st of each month, but only 7 of 12 months have a 31st day.5 Building on this, 0 0 1 * 1 fires on the 1st of every month AND every Monday, not just Mondays that fall on the 1st. None of these are syntax errors, but all produce surprising schedules.

    The common thread is that cron cannot express conditional logic: it can only list field values and operators. When a schedule depends on the actual calendar (month length, leap year, day-of-week interactions), the expression either over-triggers or under-triggers. The safest approach is to combine a conservative cron trigger with a script-level guard that exits early on non-matching days, rather than trying to encode every calendar rule into the expression itself.

    Programmatic validation in CI and deployment pipelines

    For teams that manage cron expressions in version-controlled configuration files (Kubernetes CronJob manifests, GitHub Actions workflows, or wrangler.toml), adding expression validation to the CI pipeline catches errors before they reach production. The cron-parser npm package and Python's croniter library both expose a parse function that throws on invalid input. Treating schedule validation as a test step rather than a manual review makes it impossible for a malformed expression to reach a production cluster unnoticed.

    Adding a cron validation step in Node.js

    In a Node.js test suite, a single assertion covers each expression: require('cron-parser').parseExpression('0 9 * * 1-5') throws if the expression is malformed.3 Wrap this in a test that iterates over every cron expression in your configuration and confirms each one parses without error. Running this check on every pull request catches field range violations, missing steps, and malformed operators before the schedule reaches a production environment.

    Validating logic errors that syntax checks miss

    Passing a cron expression through a syntax validator confirms the fields are well-formed, but syntax checks cannot detect logic errors. An expression like 0 0 15,31 * * is syntactically valid but fires only 10 or 11 times per year, not monthly, because not every month has a 31st day.

    Diagnosing logic errors requires inspecting the next N trigger times: paste the expression in so you can count how many times your expression actually fires per year, then read the plain-English description alongside the trigger dates to confirm they match your intent. A job you expect to run 12 times per year that fires 56 times has a logic error in its day-of-week or day-of-month field. Fix the most permissive field first and re-inspect the trigger list after each change, so a logic error like this shows up before the schedule reaches production.

    Use a syntax checker whenever you write a new cron expression, when debugging a job that is not firing on time, or when reviewing another developer's crontab entry before it is deployed to production.

    Invalid minute value

    Before
    60 * * * *
    After
    59 * * * *

    The minute field accepts 0–59 only. Using 60 causes silent failure or undefined behavior.

    Step of zero in hour field

    Before
    0 */0 * * *
    After
    0 */1 * * *

    A step of 0 is undefined. The minimum step value is 1.

    Sources for this section
    1. 1.

      Linux man7, "crontab(5) — Linux manual page," man7.org, accessed June 2026. https://www.man7.org/linux/man-pages/man5/crontab.5.html

    2. 2.

      Kelektiv, "node-cron Issue #742," GitHub, accessed June 2026. https://github.com/kelektiv/node-cron/issues/742

    3. 3.

      Harrisiirak, "cron-parser," npmjs.com, accessed June 2026. https://www.npmjs.com/package/cron-parser

    4. 4.

      Pallets Ecosystem, "croniter," pypi.org, accessed June 2026. https://pypi.org/project/croniter/

    5. 5.

      Linux man7, "cron(8) — Linux manual page," man7.org, accessed June 2026. https://www.man7.org/linux/man-pages/man8/cron.8.html

    FAQ

    Use a browser-based parser (like this tool) that shows the plain-English description and the next 5 run times. If the output matches your intent, the expression is correct. For programmatic validation, use the croniter Python library or the cron-parser npm package, both of which parse expressions and enumerate trigger times without touching the system cron daemon.

    Minute: 0 to 59. Hour: 0 to 23. Day-of-month: 1 to 31. Month: 1 to 12 (or JAN to DEC). Day-of-week: 0 to 7, where 0 and 7 are both Sunday (or SUN to SAT). Values outside these ranges are invalid. CapyToolkit's parser checks these ranges for standard 5-field cron expressions.

    The most common non-syntax causes are: the command path is wrong (use absolute paths like /usr/bin/python3 not python3), the script lacks execute permission, the script expects environment variables not set in cron's minimal environment, or the crontab file is missing a trailing newline. Check /var/log/syslog or journalctl -u cron for error messages.

    Steps must be positive integers within the field's valid range. A step of 0 is undefined (and rejected by most parsers). A step larger than the range (like */100 in the minute field) effectively fires once, at the start of the range.

    A parse error means the expression is malformed and the daemon rejects it. A logic error means the expression is syntactically valid but fires at the wrong time. Logic errors are harder to catch because cron does not report them. A parser that shows the next N run times catches logic errors that a pure syntax check misses.

    Sources
    1. 1.

      cronie Project, "crontab(5) - Linux manual page," man7.org, May 2026. https://man7.org/linux/man-pages/man5/crontab.5.html

    2. 2.

      Computer Hope, "Linux crontab command," computerhope.com, June 2025. https://www.computerhope.com/unix/ucrontab.htm

    3. 3.

      cronie Project, "cron(8) - Linux manual page," man7.org, May 2026. https://man7.org/linux/man-pages/man8/cron.8.html

    4. 4.

      Debian, "crontab(5)," manpages.debian.org, June 2025. https://manpages.debian.org/trixie/cron/crontab.5.en.html

    5. 5.

      cronie Project, "crontab(5) source file," cronie GitHub, accessed June 2026. https://github.com/cronie-crond/cronie/blob/master/man/crontab.5

    6. 6.

      "cron," Wikipedia, accessed September 2026. https://en.wikipedia.org/wiki/Cron

    7. 7.

      Quartz Scheduler, "Cron Trigger Tutorial," quartz-scheduler.org, accessed June 2026. https://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger

    8. 8.

      systemd Project, "systemd.time," systemd GitHub, accessed June 2026. https://github.com/systemd/systemd/blob/main/man/systemd.time.xml

    FAQ

    Standard 5-field Unix cron (minute, hour, day-of-month, month, day-of-week), the optional seconds-first 6-field variant, and the common shortcuts: @hourly, @daily, @weekly, @monthly, @yearly, and @reboot. @reboot parses to its run-once-at-startup description and shows no upcoming runs, because it schedules nothing in time.

    The next 5 scheduled run times from the current moment, computed using your browser's local clock and timezone.

    No. CapyToolkit doesn't send expressions anywhere. All parsing runs locally in your browser with no network requests.

    Cron uses the server's local time, and this tool uses your browser's timezone. If your server runs in UTC and your browser is in a different timezone, the displayed times will be offset from what runs in production.

    An asterisk means every valid value. In the minute field, * runs every minute; 30 runs only at minute 30. The tool translates each combination into plain English so you can confirm your intent without needing to remember the field order.

    No. L, W, and the other Quartz-specific operators are extensions to the cron format, not part of standard Unix cron, and they fail to parse here. The optional leading seconds field is the one extension this tool does parse: a seconds-first 6-field expression produces a full schedule and next-run preview.

    Additional resources