Everything you need to write, read, and debug cron expressions — in one page. Every operator, all the shorthands, 30+ common patterns, and the key differences between platforms (Unix, Quartz, AWS EventBridge, Kubernetes, GitHub Actions).
A standard Unix cron expression has five space-separated fields:
| Field | Range | Special values |
|---|---|---|
| Minute | 0–59 | |
| Hour | 0–23 | |
| Day of month | 1–31 | L (last), W (nearest weekday) — Quartz only |
| Month | 1–12 | JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC |
| Day of week | 0–7 (0 and 7 = Sunday) | SUN, MON, TUE, WED, THU, FRI, SAT; L, # — Quartz only |
Tip: Paste any expression at cronbuilder.dev to get an instant plain-English explanation and the next 10 run times.
| Operator | Name | Example | Meaning |
|---|---|---|---|
| * | Wildcard / Any | * * * * * | Match every value in this field |
| , | List | 0 9,17 * * * | At 9am and 5pm — comma-separated values |
| - | Range | 0 9-17 * * * | Every hour from 9am to 5pm inclusive |
| / | Step | */5 * * * * | Every 5 minutes — step through the range |
| L | Last | 0 0 L * * | Last day of the month (Quartz / Spring only) |
| W | Nearest weekday | 0 0 15W * * | Nearest weekday to the 15th (Quartz only) |
| # | Nth weekday | 0 10 * * 1#2 | Second Monday of the month (Quartz only) |
| ? | No specific value | 0 0 ? * 1 | Used in day-of-month or day-of-week when the other is set (Quartz / AWS) |
| Expression | Meaning |
|---|---|
*/5 (minute) | Every 5 minutes: 0, 5, 10, 15 … 55 |
0-30/5 (minute) | Every 5 minutes, only in the first half-hour: 0, 5, 10, 15, 20, 25, 30 |
*/2 (hour) | Every 2 hours: 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22 |
1/2 (hour) | Every 2 hours starting at 1am: 1, 3, 5, 7 … 23 |
Most Unix cron implementations support these shorthands as alternatives to a 5-field expression. Note: AWS EventBridge, GitHub Actions, and Kubernetes do not support these — use the explicit 5-field form.
| Shorthand | Equivalent | Runs… |
|---|---|---|
@yearly / @annually | 0 0 1 1 * | Once per year at midnight on January 1st |
@monthly | 0 0 1 * * | Once per month at midnight on the 1st |
@weekly | 0 0 * * 0 | Once per week at midnight on Sunday |
@daily / @midnight | 0 0 * * * | Once per day at midnight |
@hourly | 0 * * * * | Once per hour at the top of the hour |
@reboot | — | Once at system startup (crontab only) |
| Expression | Meaning | Notes |
|---|---|---|
* * * * * | Every minute | 1,440 runs/day |
*/2 * * * * | Every 2 minutes | |
*/5 * * * * | Every 5 minutes | Most common polling interval |
*/10 * * * * | Every 10 minutes | |
*/15 * * * * | Every 15 minutes | Quarter-hourly |
*/30 * * * * | Every 30 minutes | Same as 0,30 * * * * |
| Expression | Meaning | Notes |
|---|---|---|
0 * * * * | Every hour (top of hour) | Also: @hourly |
30 * * * * | Every hour at :30 | |
0 */2 * * * | Every 2 hours | At 00:00, 02:00, 04:00… |
0 */4 * * * | Every 4 hours | At 00:00, 04:00, 08:00, 12:00, 16:00, 20:00 |
0 */6 * * * | Every 6 hours | Midnight, 6am, noon, 6pm |
0 */12 * * * | Every 12 hours | Midnight and noon |
0 9,17 * * * | 9am and 5pm daily | Comma list |
| Expression | Meaning | Notes |
|---|---|---|
0 0 * * * | Every day at midnight | Also: @daily |
0 6 * * * | Every day at 6am | |
0 9 * * * | Every day at 9am | Most common "morning" job |
0 12 * * * | Every day at noon | |
0 18 * * * | Every day at 6pm | |
0 23 * * * | Every day at 11pm | Good for nightly backups |
| Expression | Meaning | Notes |
|---|---|---|
0 0 * * 0 | Every Sunday at midnight | Also: @weekly |
0 0 * * 1 | Every Monday at midnight | |
0 9 * * 1 | Every Monday at 9am | Weekly digest |
0 9 * * 1-5 | Weekdays at 9am | Mon–Fri only |
0 9 * * 6,0 | Weekends at 9am | Sat and Sun |
0 9 * * 1,3,5 | Mon, Wed, Fri at 9am |
| Expression | Meaning | Notes |
|---|---|---|
0 0 1 * * | 1st of every month at midnight | Also: @monthly |
0 9 1 * * | 1st of every month at 9am | Monthly report |
0 0 15 * * | 15th of every month at midnight | Mid-month billing |
0 0 1 1 * | January 1st at midnight | Also: @yearly |
0 0 1 */3 * | First day of every quarter | Jan 1, Apr 1, Jul 1, Oct 1 |
0 0 1 6,12 * | June 1st and December 1st | Twice-yearly |
Want to test any of these patterns? Paste them directly into the builder to see the next run times in your timezone.
Open Builder →| Platform | Fields | Key differences |
|---|---|---|
| Unix / Linux crontab | 5 (min hour dom month dow) | Supports @shorthands and @reboot. Timezone set via CRON_TZ env var or system timezone. |
| Quartz / Spring | 6 (sec min hour dom month dow) or 7 (+ year) | Extra seconds field. Supports L, W, # operators. ? used in dom/dow to avoid conflict. |
| GitHub Actions | 5 (standard Unix) | Always UTC. Minimum interval is every 5 minutes. Actual trigger may be delayed by up to 15 minutes under load. |
| AWS EventBridge | 6 (min hour dom month dow year) | Adds year field. Uses ? instead of * in dom/dow when the other is specified. Always UTC. |
| Kubernetes CronJob | 5 (standard Unix) | Timezone support added in Kubernetes 1.27 via spec.timeZone. Older versions default to controller timezone (usually UTC). |
| node-cron | 5 or 6 (with optional seconds) | Optional 6th field for seconds. Uses system timezone by default; pass {timezone: 'America/New_York'} option. |
| APScheduler (Python) | Named parameters | Uses keyword args (hour, minute, day_of_week) rather than a string expression. Accepts */5 notation as string values per field. |
| Unix cron | EventBridge equivalent |
|---|---|
0 9 * * * | cron(0 9 * * ? *) |
0 9 * * 1-5 | cron(0 9 ? * MON-FRI *) |
*/5 * * * * | cron(*/5 * * * ? *) |
0 0 1 * * | cron(0 0 1 * ? *) |
In most Unix cron implementations, if you specify both a day-of-month and a day-of-week, cron uses an OR — not an AND. 0 0 1 * 1 fires on the 1st of the month and every Monday, not only on Mondays that fall on the 1st.
Cloud servers (AWS, GCP, Azure, Heroku, Render) are almost always UTC. 0 9 * * * on a UTC server fires at 9am UTC — which is 4am US Eastern, 5am US Central. Set CRON_TZ=America/New_York in Linux crontab, or spec.timeZone in Kubernetes.
GitHub Actions cron jobs can be delayed by up to 15 minutes (sometimes more) during peak load. They also require a minimum interval of 5 minutes — * * * * * is silently treated as */5 * * * *.
If a job takes longer than its interval, the next run starts before the previous one finishes. Use flock -n /tmp/lockfile.lock (Linux) or check for a PID file at the start of your script to skip concurrent runs.
Most cron implementations accept both 0 and 7 for Sunday in the weekday field. Some tools (especially Quartz) use 1=Sunday, 7=Saturday — always verify when switching scheduler libraries.
Build or decode any expression instantly — no signup, no tracking, runs in your browser.
Try CronBuilder →See also: Cron job not running? 10 reasons why · Cron vs systemd timers · GitHub Actions cron schedule guide · Expression reference library