Cron Expression Builder
Expression
Fields
Presets
Next 5 Scheduled Runs
- 2026-09-23 14:00
- 2026-09-23 14:01
- 2026-09-23 14:02
- 2026-09-23 14:03
- 2026-09-23 14:04
How it works
Type a cron expression at the top, or use the visual field editors underneath. Every field has a dropdown of every valid value plus the shorthand operators (* any, */N every N, 1-5 range, 1,3,5 list). The tool shows three things live: the original expression, a plain-English description ("Every 15 minutes from 9am to 5pm, Monday to Friday"), and the next five concrete run times in your local timezone.
Cron expressions have exactly 5 fields separated by spaces. It is the same format used by Unix crontab, Kubernetes CronJob, GitHub Actions schedule, GitLab CI, AWS EventBridge, and almost every other scheduler you will encounter:
┌──────── minute (0–59) │ ┌────── hour (0–23) │ │ ┌──── day of month (1–31) │ │ │ ┌── month (1–12) │ │ │ │ ┌ day of week (0–6, Sunday = 0) │ │ │ │ │ * * * * *
A few useful reference expressions worth knowing by heart: • `0 * * * *`: at minute 0 of every hour (hourly) • `0 0 * * *`: every day at midnight • `*/15 * * * *`: every 15 minutes • `0 9 * * 1-5`: 9:00 Mon–Fri (typical business day) • `0 0 1 * *`: first of every month, midnight • `0 2 * * 0`: Sunday at 2:00 (common for weekly backups) • `30 6 1-7 * 1`: 6:30 on the first Monday of the month
The tool ships with a preset library for the most common schedules so you don't have to remember the exact syntax. The "next run times" calculation uses the same algorithm as standard crontab implementations (cron-parser / croniter), so what you see here is what your production scheduler will do.
One gotcha worth calling out: when both day-of-month and day-of-week are restricted (neither is *), standard cron runs the job if either matches, not both. So `0 0 15 * 1` fires on the 15th of every month and on every Monday, not only on Mondays that happen to be the 15th. This catches everyone at least once.
Frequently Asked Questions
What cron format is used?
- Standard 5-field Unix crontab: minute, hour, day-of-month, month, day-of-week. Supports every operator you would expect: * (any), */N (every N), ranges like 1-5, lists like 1,3,5, and combinations like */2,15-20. This is the same format used by Unix crontab, Kubernetes CronJob, GitHub Actions, GitLab CI, and AWS EventBridge.
Are seconds supported?
- No. This is a 5-field tool. 6-field cron (with a leading seconds column) is a Quartz / Spring-specific extension used by Java schedulers. If you are editing a Spring @Scheduled or a Quartz job, most schedulers accept the 5-field form with an implicit 0 seconds.
How are the next run times calculated?
- Using the same logic as the standard cron-parser library: the tool steps forward from now, field by field, until it finds the next timestamp that matches. Times are shown in your browser's local timezone; change the clock's timezone in your OS and refresh to see them in UTC.
What's the difference between 0 0 * * 1-5 and */5 9-17 * * 1-5?
- The first fires at midnight Monday–Friday (five times a week). The second fires every 5 minutes from 09:00 to 17:00 Monday–Friday (≈ 600 times a week). Always read your cron expressions out loud in English. The tool's human-readable line will catch most mistakes before they reach production.
Why does my schedule run twice as often as I expected?
- The classic trap: when both day-of-month and day-of-week are restricted, standard cron runs if EITHER matches, not both. `0 0 15 * 1` means "midnight on the 15th OR midnight on any Monday", not "only Mondays that fall on the 15th". Leave one of the two fields as * to get a single condition.
Does this work for Kubernetes CronJob / GitHub Actions / GitLab CI?
- Yes. All three use the standard 5-field format this tool generates. One thing to double-check: GitHub Actions runs on UTC regardless of where your repo lives, so "0 9 * * *" in a GitHub workflow fires at 9:00 UTC, not 9:00 local.
Is the cron expression sent anywhere?
- No. The parsing, validation and next-run calculation all run as JavaScript in your browser tab. The DevTools Network tab confirms no outbound request fires. Nothing is stored or logged.
How do I write a cron expression that runs on the last day of the month?
- Standard 5-field cron does not have an "L" (last) operator; that is a Quartz / Spring extension. To run on the actual last day of every month with standard cron, you cannot do it in a single expression. The usual workaround is to run on the 28th, 29th, 30th and 31st with a script that checks `[ "$(date -d tomorrow +%d)" -eq 1 ] && do-the-job`. On Quartz / Spring (`@Scheduled`) you can write `0 0 0 L * ?` directly.
What's the difference between 0 */2 * * * and 0 0,2,4,6,8,10,12,14,16,18,20,22 * * *?
- They are identical: both fire every two hours at minute 0. The `*/2` form is shorthand for "every 2nd value starting from 0". For odd starting offsets (e.g. "every 2 hours starting at 1am") you need the explicit list form `0 1,3,5,7,9,11,13,15,17,19,21,23 * * *`, because */2 always starts from 0.
Can I use month names and weekday names instead of numbers?
- In most schedulers yes: JAN-DEC for months, SUN-SAT for weekdays, case-insensitive, so `0 9 * * MON-FRI` means the same as `0 9 * * 1-5`. AWS EventBridge requires the name form for weekdays. This editor validates digits and the operators * - / , only, so type `0 9 * * 1-5` here; numeric form is the safer choice across platforms anyway.
Cron expression cheat sheet: common schedules
Copy-paste reference for the schedules you write most often. All expressions are standard 5-field crontab format: minute hour day-of-month month day-of-week.
| Expression | Runs | Typical use |
|---|---|---|
| * * * * * | Every minute | Smoke-test that your scheduler is alive |
| */5 * * * * | Every 5 minutes | Frequent polling, monitoring scrapes |
| */15 * * * * | Every 15 minutes | Cache warmup, metric collection |
| 0 * * * * | Every hour at :00 | Hourly digests, log rotations |
| 30 * * * * | Every hour at :30 | Stagger jobs to avoid top-of-hour spikes |
| 0 */2 * * * | Every 2 hours | Mid-frequency batch jobs |
| 0 9 * * * | Daily at 09:00 | Morning report, daily email digest |
| 0 0 * * * | Daily at midnight | Day-end aggregation, log rotation |
| 0 2 * * * | Daily at 02:00 | Backups (low-traffic window) |
| 0 9 * * 1-5 | 9:00 Mon–Fri | Business-day notifications, standup reminders |
| 0 9 * * 1 | Monday 09:00 | Weekly Monday-morning report |
| 0 2 * * 0 | Sunday 02:00 | Weekly backup, weekly cleanup |
| 0 0 1 * * | First of month, 00:00 | Monthly billing, monthly archive |
| 0 0 1 1 * | 1 Jan, 00:00 (yearly) | Annual reset, year-end report |
| 0 0 1 */3 * | Every 3 months, day 1 | Quarterly job |
| @hourly | Top of every hour | Shortcut for `0 * * * *` (not supported by all schedulers) |
| @daily | Midnight every day | Shortcut for `0 0 * * *` |
| @weekly | Sunday at 00:00 | Shortcut for `0 0 * * 0` |
| @monthly | First of month, 00:00 | Shortcut for `0 0 1 * *` |
| @yearly | 1 Jan, 00:00 | Shortcut for `0 0 1 1 *` |
| @reboot | On scheduler start | Once per cron daemon start (Unix cron only) |
Standard 5-field format defined by POSIX crontab. The @-shortcuts (@hourly, @daily, etc.) are a Vixie cron extension supported by most Unix cron, Linux systemd timers via OnCalendar, and node-cron, but NOT by Kubernetes CronJob, GitHub Actions, AWS EventBridge or Quartz. Use the explicit 5-field form for cross-platform compatibility.