Cron Next Run Calculator

Paste a cron expression to see the next 5 firings in UTC.

Next 5 firings (UTC)

  1. 2026-05-04 09:00:00 UTC
  2. 2026-05-11 09:00:00 UTC
  3. 2026-05-18 09:00:00 UTC
  4. 2026-05-25 09:00:00 UTC
  5. 2026-06-01 09:00:00 UTC

Convert to your local timezone by subtracting your UTC offset. Most cron daemons run in the server's local timezone, not UTC.

Paste a 5-field POSIX cron expression and the calculator returns the next five times it will fire in UTC. The parser is the open-source cron-parser library, the same engine used by node-cron, Bull, BullMQ, and most Node-based job-runners — so the output matches what your application would actually do at runtime, not just what the man page implies. No expression is sent to a server: parsing happens in your browser. For schedule planning across zones, pair the result with the world clock; for one-off countdowns to a single cron firing, drop the result into the days-from-today page.

Common use cases

  • Verifying a scheduled job before deploying. You wrote `0 2 * * 0` and want to confirm it fires at 02:00 UTC every Sunday before you push to prod. The calculator shows the next five Sunday firings; if the dates look wrong, your expression is wrong. Saves a 15-minute round-trip of "deploy, wait a week, see what happens".
  • Debugging a job that did not fire. A job was supposed to run last Wednesday but did not. Plug the expression into the calculator with `from` set to the start of that week — if Wednesday is missing from the next-five list, the expression itself is the bug. The most common cause is the day-of-month / day-of-week OR-semantics gotcha (covered in the edge cases below).
  • Migrating from Quartz to POSIX cron. Quartz uses a 6-or-7-field format with seconds and an optional year; POSIX uses 5 fields. When porting jobs from Spring/Quartz to a Linux crontab or to BullMQ, paste the new 5-field expression here to confirm it still fires when expected before swapping over.
  • Capacity planning around batch windows. You need to know when the next 10 nightly ETL runs will land so you can pre-provision compute. Bump the count and read off the times. Combine with the days-from-today page to convert each firing into a wall-clock date.

How it works

cron-parser tokenises the expression into five fields (minute, hour, day-of-month, month, day-of-week), validates each against its allowed range and step/range/list syntax, then walks forward from the supplied "from" date one minute at a time, emitting a hit whenever every field matches. The walk is bounded — invalid expressions throw immediately rather than spinning forever. All times are computed and returned in UTC; the calculator does not apply your local timezone, because cron expressions in a Linux crontab are evaluated in the server's TZ (which is rarely your laptop's TZ) and showing UTC keeps the answer unambiguous.

Worked examples

Every Monday at 09:00 UTC

Enter `0 9 * * 1` with from = 2026-04-28 (a Tuesday).

Result: First firing: 2026-05-04 (the following Monday) at 09:00 UTC.

Day-of-week uses 0–6 with 0 = Sunday, or names like MON. Cron parses 1 as Monday in this position. The next four firings are exactly seven days apart because nothing else in the expression varies.

Every 15 minutes

Enter `*/15 * * * *` with from = 2026-04-28 10:02 UTC.

Result: First firing: 10:15 UTC. Then 10:30, 10:45, 11:00, 11:15.

The step `*/15` in the minute field means "every 15 minutes starting at minute 0", so the schedule is :00, :15, :30, :45 — never :02, :17, :32, :47. If you want a 15-minute gap from an arbitrary start, you need a different scheduler — cron is calendar-aligned, not interval-based.

Midnight UTC on February 29 only

Enter `0 0 29 2 *`.

Result: Next firing: midnight UTC, year 2028 (the next leap year after 2026).

Cron silently accepts February 29 in any year; it just never fires in non-leap years. This is a frequent source of confusion when people use Feb 29 as a "never fire" canary — it does eventually fire, every four years (with the century rule), surprising the developer who set it.

Edge cases & gotchas

  • Day-of-month and day-of-week are OR, not AND. POSIX cron is famously surprising here: if BOTH day-of-month and day-of-week are restricted (neither is `*`), the job fires when EITHER matches. So `0 0 1 * 1` fires on the 1st of every month AND on every Monday — not "the 1st, but only if it is a Monday". To restrict to Mondays-that-are-the-1st you need a workaround like `[ "$(date +\%u)" = "1" ] && job` inside the script, or use a scheduler that supports AND semantics.
  • cron-parser is timezone-aware; system cron is not. The calculator runs in UTC by default. The cron daemon on a Linux box runs in the system's timezone (usually whatever `/etc/timezone` says), and crontabs written for one server may fire at a different wall-clock hour on another. If your job needs to land at "9 AM London time", set the server TZ explicitly (`TZ=Europe/London` at the top of the crontab) — relying on the default is fragile.
  • DST transitions skip or duplicate firings. On the spring-forward day, cron jobs scheduled inside the missing hour (typically 02:00–03:00 local) do not fire. On the fall-back day, jobs scheduled inside the duplicated hour fire twice. The calculator hides this because it works in UTC, but if you re-base into a DST-observing zone you will see the gap. Use UTC for any job whose correctness depends on running exactly once per scheduled minute.
  • Months are 1-12, days are 1-31, weekdays are 0-6 (or 1-7). Unlike JavaScript Date, cron months are not zero-indexed: January is 1, December is 12. Day-of-week accepts 0 OR 7 for Sunday, which has bitten parsers that assumed 0-6. cron-parser supports both. Also note: cron does not validate impossible dates like Feb 30 — it simply never matches them, fires nothing, and gives no warning.

Frequently asked questions about Cron Next Run Calculator

What's the difference between 5-field and 6-field cron?

POSIX cron (Linux, BSD, macOS) uses 5 fields: minute hour day month weekday. Quartz (Java/Spring) and some others use 6 (adds seconds at the front) or 7 (adds optional year at the end). This calculator parses the 5-field format. If your scheduler uses 6 fields, drop the leading seconds field before pasting; if it uses 7, drop the seconds AND the year.

Why does `*/5 * * * *` fire at :05, :10, :15… and not five minutes from now?

Cron is calendar-aligned, not relative. `*/5` in the minute field means "every minute that is divisible by 5", so the schedule is fixed at :00, :05, :10, …, :55 every hour, regardless of when the daemon started. If you need "5 minutes from now, then every 5 minutes", you need a setInterval-style scheduler — or rewrite the job to manage its own timing.

Are special strings like `@daily`, `@hourly`, `@reboot` supported?

cron-parser supports the time-based aliases: `@yearly` (`0 0 1 1 *`), `@monthly` (`0 0 1 * *`), `@weekly` (`0 0 * * 0`), `@daily`/`@midnight` (`0 0 * * *`), `@hourly` (`0 * * * *`). It does NOT support `@reboot` because that is a system-event hook with no cron semantics — there is no "next firing" to compute.

Does this handle L (last day of month), W (nearest weekday), # (nth weekday)?

cron-parser supports L, W, and # — these are Quartz extensions adopted by some Linux cron implementations. `0 0 L * *` fires on the last day of each month (handling 28/29/30/31 correctly). `0 0 LW * *` fires on the nearest weekday to the last day. `0 0 * * 1#2` fires on the second Monday of each month. Standard POSIX cron does NOT support these — your daemon may differ.

Will the calculator agree with my Linux crontab in production?

Yes if your TZ is UTC. Linux cron evaluates the expression against the system TZ, so if your server is set to UTC the times will match exactly. If your server is set to a local TZ (which is the default on most distros), shift the calculator output by the TZ offset — or set `TZ=UTC` at the top of your crontab so both you and the daemon agree.

How do I express "the first weekday of every month"?

`0 0 1-3 * *` fires on the 1st, 2nd, OR 3rd of each month — too greedy. The clean solution is to fire daily and exit early in the script: `0 0 * * 1-5 [ "$(date +\%d)" -le 3 ] && job`. Or use a scheduler with AND semantics. The Quartz extension `0 0 1W * *` fires on the nearest weekday to the 1st — supported by cron-parser, sometimes by Linux cron.

Glossary

Cron expression
A 5-field string describing a recurring schedule: minute (0-59), hour (0-23), day-of-month (1-31), month (1-12), day-of-week (0-7, 0 and 7 both Sunday). Fields can use `*`, ranges (`1-5`), lists (`1,3,5`), steps (`*/15`), or names (MON, JAN).
POSIX cron
The standard cron format defined by IEEE Std 1003.1, used by Linux, BSD, and macOS. 5 fields, no seconds, no year, no L/W/# extensions. Most online cron tutorials describe POSIX cron.
Quartz cron
An extended cron format from the Java Quartz scheduler. 6 or 7 fields (adds seconds and optional year), supports L (last day), W (nearest weekday), # (nth weekday). Used by Spring Scheduler and ports to other languages.
Step value
The `/N` syntax for "every N units within the range". `*/15` in the minute field means every 15 minutes (:00, :15, :30, :45). `1-30/5` means 1, 6, 11, 16, 21, 26 — step within an explicit range.
OR semantics
POSIX cron quirk: when day-of-month and day-of-week are both restricted (not `*`), a firing happens when EITHER matches. `0 0 15 * 1` fires on the 15th of every month AND on every Monday — not just on the 15ths that are Mondays.
@daily / @hourly aliases
Convenience strings that expand to common expressions: `@hourly` = `0 * * * *`, `@daily` = `0 0 * * *`, `@weekly` = `0 0 * * 0`, `@monthly` = `0 0 1 * *`, `@yearly` = `0 0 1 1 *`. `@reboot` is a system-event hook, not a schedule.

Related Time Tools