Cron expressions follow a simple five-field syntax, but writing the right one from memory is surprisingly easy to get wrong — especially when dealing with step values, ranges, or day-of-week numbering differences across platforms. This reference covers the expressions you'll reach for most often, organised by how frequently they run.

If you want to test any of these expressions against a live clock and see the next five run times, use the Cron Expression Parser.

Quick Reference — All Common Expressions

ExpressionMeaningNotes
* * * * *Every minuteMaximum resolution in standard cron
*/5 * * * *Every 5 minutesAlso: */10, */15, */30
*/15 * * * *Every 15 minutesFour times per hour
*/30 * * * *Every 30 minutesTwice per hour
0 * * * *Every hour (on the hour)At :00 of every hour
0 */2 * * *Every 2 hoursAt 00:00, 02:00, 04:00…
0 */6 * * *Every 6 hoursAt 00:00, 06:00, 12:00, 18:00
0 0 * * *Every day at midnightUTC unless server TZ configured
0 6 * * *Every day at 6:00amChange first 0 for minutes past
0 9 * * 1-5Weekdays at 9:00amMon–Fri only
0 9 * * 0Every Sunday at 9:00am0 = Sunday on most systems
0 9 * * 1Every Monday at 9:00am1 = Monday
0 0 * * 0Every Sunday at midnightWeekly cleanup/backup pattern
0 0 1 * *1st of every month at midnightMonthly billing, reports
0 0 15 * *15th of every month at midnightMid-month run
0 0 1 1 *January 1st at midnightAnnual run
0 0 1 */3 *1st of every quarterJan, Apr, Jul, Oct
30 8 * * 1-5Weekdays at 8:30amDaily standup reminder pattern
0 0,12 * * *Twice a day — midnight and noonComma = list of values
0 8-18 * * 1-5Every hour, 8am–6pm, weekdaysBusiness hours polling

Every N Minutes

The step operator / divides the range by the step value. In the minute field, */5 means every value from 0 to 59 that is divisible by 5 — so 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55. It runs twelve times per hour.

*/5 * * * * # Every 5 minutes */10 * * * * # Every 10 minutes */15 * * * * # Every 15 minutes (4x per hour) */30 * * * * # Every 30 minutes (2x per hour)

Note: you cannot schedule a job to run every 2 minutes and 30 seconds — standard cron has one-minute resolution. If you need sub-minute scheduling, you need either a platform that supports a seconds field (AWS EventBridge, Quartz) or a workaround like running the process twice per minute entry.

Hourly Patterns

0 * * * * runs at the top of every hour — minute 0, every hour. If you want to run at a specific minute past each hour, change the first field. 30 * * * * runs at half past every hour.

0 * * * * # Top of every hour (:00) 15 * * * * # 15 minutes past every hour (:15) 30 * * * * # Half past every hour (:30) 0 */2 * * * # Every 2 hours, on the hour 0 */4 * * * # Every 4 hours: 00:00, 04:00, 08:00… 0 */6 * * * # Every 6 hours: 00:00, 06:00, 12:00, 18:00

Daily Patterns

Daily jobs are among the most common. The key thing to confirm is what timezone the cron daemon is running in — 0 0 * * * runs at midnight in the server's local timezone, which may not be midnight in your timezone. Always confirm with your infrastructure team or check timedatectl on Linux.

0 0 * * * # Every day at midnight (server TZ) 0 6 * * * # Every day at 6:00am 0 9 * * * # Every day at 9:00am 0 23 * * * # Every day at 11:00pm 0 0,12 * * * # Twice daily: midnight and noon

Weekday and Weekend Patterns

Day-of-week numbering is a common source of bugs. On most systems (Linux cron, GitHub Actions, AWS), 0 and 7 both mean Sunday, and 1–6 mean Monday–Saturday. Some older systems use 1 = Sunday. Always verify on your platform.

0 9 * * 1-5 # 9am, Monday through Friday 0 9 * * 1 # 9am every Monday 0 9 * * 5 # 9am every Friday 0 0 * * 0 # Midnight every Sunday 0 0 * * 6,0 # Midnight Saturday and Sunday 30 8 * * 1-5 # 8:30am weekdays

Monthly and Quarterly Patterns

0 0 1 * * # Midnight on the 1st of every month 0 0 15 * * # Midnight on the 15th of every month 0 0 1 */3 * # Quarterly: Jan 1, Apr 1, Jul 1, Oct 1 0 0 1 1,7 * # Twice a year: Jan 1 and Jul 1 0 0 1 1 * # Once a year: January 1st at midnight

Platform-Specific Syntax

GitHub Actions

GitHub Actions uses standard 5-field cron in UTC under the schedule trigger. The minimum supported interval is every 5 minutes — * * * * * will be throttled. Schedules may run up to 15 minutes late under load.

on: schedule: - cron: '0 9 * * 1-5' # Weekdays at 9am UTC - cron: '0 0 1 * *' # Monthly on the 1st

AWS EventBridge (CloudWatch Events)

AWS uses a 6-field cron with a seconds field first, and uses ? as a required placeholder when specifying either day-of-month or day-of-week but not both. All times are UTC.

cron(0 9 * * ? *) # Every day at 9am UTC cron(0 9 ? * MON-FRI *) # Weekdays 9am UTC cron(0 0 1 * ? *) # 1st of month midnight UTC

Kubernetes CronJobs

Kubernetes uses standard 5-field cron. The timezone is determined by the kube-controller-manager's timezone, which defaults to UTC. Kubernetes 1.27+ supports a timeZone field in the CronJob spec.

spec: schedule: "0 9 * * 1-5" # Weekdays 9am timeZone: "America/New_York" # Kubernetes 1.27+
Test any cron expression live Paste an expression to see what it means in plain English and when it runs next.
Open Cron Parser →

Common Mistakes

The most frequent cron errors in production: running a job at 0 0 * * * and forgetting the server is in UTC when you expected a local midnight. Using 0 0 * * 7 for Sunday and discovering your platform treats 7 as invalid (use 0 instead, or both 0,7 for safety). Setting 0 0 30 2 * for a February 30th job that never runs — always validate month and day combinations. Using * * * * * in GitHub Actions and wondering why the job runs erratically — the minimum is */5 * * * *.


Frequently Asked Questions

How do I run a cron job every 2 minutes?
Use */2 * * * *. The step operator /2 in the minute field means every value divisible by 2: 0, 2, 4, 6... 58. This runs 30 times per hour. For sub-minute intervals, standard cron is not the right tool — use a platform with a seconds field, or a dedicated job scheduler.
What does ? mean in a cron expression?
The ? character means "no specific value" and is used in platforms like AWS EventBridge and Quartz Scheduler that require you to explicitly indicate whether day-of-month or day-of-week is intentionally unset. Standard Unix cron does not support ? — use * instead. If you see a ? in a cron expression written for Linux cron, it will cause a parse error.
How do I run a job on the last day of the month?
Standard 5-field cron has no "last day of month" operator. The common workaround is to schedule for the 28th (0 0 28 * *) which exists in every month, or use a platform-specific extension. Some cron implementations support L in the day field for "last," but this is not universal. Alternatively, run daily and check inside the job whether it is the last day of the month.
Why is my cron job running at the wrong time?
Almost always a timezone issue. Cron runs in the server's local timezone, which is often UTC in cloud environments. A job set to 0 9 * * * runs at 9am in whatever timezone the cron daemon is using. Check your server timezone with timedatectl on Linux or check the platform documentation for hosted schedulers like GitHub Actions (always UTC) or AWS EventBridge (always UTC).

Related reading

Reference
Unix Timestamp to Date