Cron Expression Cheat Sheet — Every Schedule You'll Ever Need
Nobody memorizes cron syntax. You look it up, copy the expression, paste it, and move on. This page is the reference you'll keep coming back to — every common schedule, the field-by-field syntax, and the mistakes that silently break production jobs.
The 5 Cron Fields
A standard cron expression has five space-separated fields. Left to right, smallest unit to largest:
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12 or JAN-DEC)
│ │ │ │ ┌───────────── day of week (0-7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * *
The expression fires when all five fields match the current time. An asterisk (*) means "every value." A mnemonic: "Minute, Hour, Day, Month, Weekday" — left to right, small to big.
Operators
| Operator | Meaning | Example |
|---|---|---|
* | Every value | * * * * * — every minute |
, | List of values | 0,15,30,45 — at minutes 0, 15, 30, 45 |
- | Range | 9-17 — hours 9 through 17 |
/ | Step (every Nth) | */5 — every 5th value |
Important: */5 in the minute field means "at minute 0, 5, 10, 15, 20..." — it is anchored to zero, not to the time you saved the job. If you save at 12:03, the next run is 12:05, not 12:08.
Every-Minute and Every-N-Minutes
| Schedule | Expression |
|---|---|
| Every minute | * * * * * |
| Every 5 minutes | */5 * * * * |
| Every 10 minutes | */10 * * * * |
| Every 15 minutes | */15 * * * * |
| Every 30 minutes | */30 * * * * |
* * * * * means every single minute — 1,440 times per day. Make sure your job can complete in under 60 seconds, or you'll have overlapping runs.
Hourly Schedules
| Schedule | Expression |
|---|---|
| Every hour (at :00) | 0 * * * * |
| Every hour at :30 | 30 * * * * |
| Every 2 hours | 0 */2 * * * |
| Every 6 hours | 0 */6 * * * |
| Every 12 hours | 0 */12 * * * |
Daily Schedules
| Schedule | Expression |
|---|---|
| Midnight | 0 0 * * * |
| 6:00 AM | 0 6 * * * |
| 9:00 AM | 0 9 * * * |
| Noon | 0 12 * * * |
| 5:00 PM | 0 17 * * * |
| 9:30 AM | 30 9 * * * |
| Twice daily (9 AM and 6 PM) | 0 9,18 * * * |
Weekly Schedules
| Schedule | Expression |
|---|---|
| Every Monday at 9 AM | 0 9 * * 1 |
| Every Friday at 5 PM | 0 17 * * 5 |
| Weekdays at 9 AM | 0 9 * * 1-5 |
| Weekends at midnight | 0 0 * * 0,6 |
| Sunday at midnight | 0 0 * * 0 |
| Mon, Wed, Fri at 8 AM | 0 8 * * 1,3,5 |
Day-of-week numbering: 0 = Sunday, 1 = Monday, ..., 6 = Saturday, 7 = Sunday (again). Both 0 and 7 are Sunday. Use names (MON, TUE) if your system supports them.
Monthly and Yearly Schedules
| Schedule | Expression |
|---|---|
| 1st of every month at midnight | 0 0 1 * * |
| 15th of every month at 9 AM | 0 9 15 * * |
| Every quarter (Jan, Apr, Jul, Oct) | 0 0 1 1,4,7,10 * |
| January 1st at midnight | 0 0 1 1 * |
| Last day of month | Not possible in standard cron* |
*Standard 5-field cron cannot express "last day of month." Some schedulers (Quartz, AWS EventBridge) support the L character: 0 0 L * *. For standard cron, use a wrapper script that checks if tomorrow is the 1st.
Business Hours Pattern
This is the most common real-world pattern — run during office hours on workdays:
*/15 9-17 * * 1-5
This means: every 15 minutes, between 9:00 AM and 5:59 PM, Monday through Friday. Perfect for health checks, sync jobs, or dashboard refreshes that only matter during business hours.
Platform Differences
Not all cron implementations are identical:
- Standard crontab (Linux) — 5 fields, no seconds, no
L/W/# - Quartz (Java/Spring) — 6-7 fields with seconds, supports
L,W,# - AWS EventBridge — 6 fields with year, uses
?for unspecified day-of-month or day-of-week - GitHub Actions — standard 5 fields, runs in UTC only
- Kubernetes CronJob — standard 5 fields, timezone configurable since v1.27
When in doubt, paste your expression into our Cron Tester to see the next run times before deploying.
Common Mistakes
- Forgetting the timezone — cron runs in the server's system timezone. A job set for
0 9 * * *runs at 9 AM server time. If your server is UTC and you're in EST, that's 4 AM your time. GitHub Actions always runs in UTC. - Day-of-month AND day-of-week — in standard cron, specifying both creates an OR condition.
0 0 15 * 5runs on the 15th of every month and every Friday, not "Friday the 15th." - Overlapping runs — if a job takes 10 minutes and runs every 5 minutes, you'll have parallel instances. Use a lock file or
flockto prevent overlap. - No error handling — cron swallows output by default. Redirect to a log:
*/5 * * * * /path/to/script.sh >> /var/log/myjob.log 2>&1 - The
*/Ntrap —*/5runs at minutes 0, 5, 10... not "every 5 minutes from when I saved." If you save at 12:03, the next run is still 12:05.
Quick Reference: Day-of-Week Numbers
| Number | Day | Number | Day |
|---|---|---|---|
| 0 | Sunday | 4 | Thursday |
| 1 | Monday | 5 | Friday |
| 2 | Tuesday | 6 | Saturday |
| 3 | Wednesday | 7 | Sunday |
Frequently Asked Questions
How do I test a cron expression before deploying?
Paste it into our Cron Tester to see a human-readable description and the next 5-10 run times. Or use Cron Builder to construct one visually.
Can cron run a job every 45 seconds?
No — standard cron's smallest unit is one minute. For sub-minute scheduling, use a loop inside the script, systemd timers, or a scheduler that supports seconds (like Quartz).
Does 0 */2 * * * run at every even hour or every 2 hours from midnight?
Every even hour: 0:00, 2:00, 4:00, 6:00... The step is anchored to the field's minimum (0 for hours). It does not mean "every 2 hours from when the job was created."
How do I run a job on the last day of every month?
Standard cron can't express this directly. Use a script wrapper: [ "$(date +\%d -d tomorrow)" = "01" ] && /path/to/job.sh. Or use a scheduler that supports the L character.
Paste any cron expression and see the next run times plus a human-readable description. Runs 100% in your browser.
Cron Tester → Cron Builder →