Skip to main content
← All Articles Β· Β· 10 min read

Cron Expression Generator: Schedule Jobs with Cron Syntax

Generate and validate cron expressions online for free. Learn cron syntax, common scheduling patterns, and how to schedule jobs in Linux, Docker, and cloud platforms.

croncron-generatorschedulingdeveloper-toolsdevops

Cron is one of the most enduring pieces of Unix infrastructure. First appearing in Unix Version 7 in 1979, cron (short for β€œchronos”, the Greek word for time) has been scheduling background jobs for over four decades. Today, cron expressions power everything from Linux system tasks to Kubernetes CronJobs, GitHub Actions schedules, AWS EventBridge rules, and cloud function triggers.

The syntax is compact and expressive, but it’s also cryptic enough that even experienced developers reach for a reference every time they need to write one. This guide covers cron syntax from the ground up, explains common scheduling patterns, and shows you how to use a cron expression generator to build and validate expressions without memorizing the spec.

What Is Cron?

Cron is a time-based job scheduler. You define a schedule as a cron expression (a string of five or six fields), associate it with a command, and cron runs that command automatically at every matching time.

The most common use cases:

  • System maintenance β€” clean up temp files, rotate logs, run backups
  • Scheduled reports β€” generate and email daily/weekly reports
  • Data pipelines β€” pull data from APIs, sync databases, run ETL jobs
  • Health checks β€” ping services and alert if they don’t respond
  • Cache warming β€” pre-populate caches before peak traffic hours
  • Certificate renewal β€” Let’s Encrypt certbot runs as a cron job
  • CI/CD triggers β€” nightly builds, scheduled test runs

Cron Expression Syntax

A standard cron expression has five fields:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ minute (0–59)
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ hour (0–23)
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ day of month (1–31)
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ month (1–12 or JAN–DEC)
β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ day of week (0–7, where 0 and 7 are Sunday, or SUN–SAT)
β”‚ β”‚ β”‚ β”‚ β”‚
* * * * *  command

Many modern systems (Quartz scheduler, AWS, some Linux cron variants) add a sixth field for seconds:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ second (0–59)
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ minute (0–59)
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ hour (0–23)
β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ day of month (1–31)
β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ month (1–12)
β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ day of week (0–7)
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
* * * * * *  command

Special Characters

CharacterMeaningExample
*Every value* * * * * β€” every minute
,List of values1,15,30 β€” at minutes 1, 15, and 30
-Range9-17 β€” hours 9 through 17
/Step/interval*/15 β€” every 15 units
LLast (some implementations)L in day-of-month = last day of month
WNearest weekday (Quartz)15W = nearest weekday to the 15th
#Nth weekday (Quartz)2#3 = third Tuesday
?No specific value (Quartz)Used when specifying day-of-month OR day-of-week

Step Values

The / operator creates repeating intervals:

*/5  β€” every 5 units (0, 5, 10, 15, ...)
0/5  β€” same thing (explicit start at 0)
1/5  β€” 1, 6, 11, 16, ... (start at 1)
10/5 β€” 10, 15, 20, ... (start at 10)

You can combine / with ranges:

0-30/5  β€” every 5 minutes within the first 30 minutes of the hour

Common Cron Expression Patterns

Basic Schedules

# Every minute
* * * * *

# Every hour (at :00)
0 * * * *

# Every day at midnight
0 0 * * *

# Every day at noon
0 12 * * *

# Every day at 2:30 AM
30 2 * * *

# Every Sunday at midnight
0 0 * * 0

# Every Monday at 9 AM
0 9 * * 1

# First day of every month at midnight
0 0 1 * *

# Last day of every month (non-standard, depends on implementation)
0 0 28-31 * * test $(date -d tomorrow +%d) -eq 1 && command

Interval Schedules

# Every 5 minutes
*/5 * * * *

# Every 15 minutes
*/15 * * * *

# Every 30 minutes
*/30 * * * *

# Every 2 hours
0 */2 * * *

# Every 6 hours (at midnight, 6 AM, noon, 6 PM)
0 0,6,12,18 * * *
# or equivalently:
0 */6 * * *

# Every 12 hours (midnight and noon)
0 0,12 * * *

Day-Specific Schedules

# Weekdays only at 9 AM
0 9 * * 1-5

# Weekdays only at 9 AM and 5 PM
0 9,17 * * 1-5

# Weekends only at noon
0 12 * * 0,6

# Monday, Wednesday, Friday at 8 AM
0 8 * * 1,3,5

# Every Tuesday and Thursday at 3 PM
0 15 * * 2,4

Monthly Schedules

# First of every month at midnight
0 0 1 * *

# 15th of every month at noon
0 12 15 * *

# First Monday of every month (requires day-of-week with specific month day)
0 9 1-7 * 1

# Every quarter (January, April, July, October)
0 0 1 1,4,7,10 *

# First of January (yearly)
0 0 1 1 *

Business-Oriented Schedules

# Business hours check every 5 minutes, weekdays 8 AM–6 PM
*/5 8-18 * * 1-5

# Daily report at end of business day (5 PM weekdays)
0 17 * * 1-5

# Weekly digest every Monday morning at 7 AM
0 7 * * 1

# Monthly invoice on the 1st at 8 AM
0 8 1 * *

# Quarterly summary on the 1st of each quarter at midnight
0 0 1 1,4,7,10 *

Cron on Different Platforms

Linux (crontab)

Edit your crontab with crontab -e. Each line follows the standard 5-field format:

# Run a backup script daily at 2 AM
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# Clean temp files every Sunday at 3 AM
0 3 * * 0 find /tmp -mtime +7 -delete

# Check disk usage every hour and alert if >90%
0 * * * * /usr/local/bin/check_disk.sh

Key tips for Linux cron:

  • Always use absolute paths in cron commands β€” cron runs with a minimal environment
  • Redirect output to a log file or /dev/null to avoid email accumulation
  • Test your command manually before scheduling it
  • Use MAILTO="" to suppress emails if you’re logging to files
# Useful crontab header
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""

# Your jobs below
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

System Cron (/etc/cron.d/)

For system-level jobs, drop a file in /etc/cron.d/ with a username field:

# /etc/cron.d/my-service
0 2 * * * root /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Docker / Kubernetes CronJob

Kubernetes CronJobs use standard 5-field cron syntax:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: daily-report
spec:
  schedule: "0 9 * * 1-5"   # Weekdays at 9 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: reporter
            image: my-reporter:latest
          restartPolicy: OnFailure

Key Kubernetes considerations:

  • Times are in UTC
  • Use concurrencyPolicy: Forbid to prevent overlapping job runs
  • Set successfulJobsHistoryLimit and failedJobsHistoryLimit to avoid accumulating completed pods

GitHub Actions

on:
  schedule:
    - cron: '0 9 * * 1-5'  # Weekdays at 9 AM UTC
    - cron: '0 0 * * 0'    # Every Sunday at midnight UTC

Note: GitHub Actions schedules are in UTC. There’s a known delay during high-load periods β€” the job may run several minutes after the scheduled time.

AWS EventBridge (CloudWatch Events)

AWS supports two formats β€” cron and rate expressions:

# Cron format (AWS uses 6 fields with year)
cron(0 9 * * ? *)    # Every day at 9 AM UTC
cron(0 9 ? * MON-FRI *)  # Weekdays at 9 AM UTC

# Rate format (simpler for intervals)
rate(5 minutes)
rate(1 hour)
rate(7 days)

AWS-specific quirks:

  • The day-of-week and day-of-month fields can’t both be specified β€” use ? for one of them
  • Year field is required (use * for any year)
  • Uses MON-FRI style names for days

Heroku Scheduler

Heroku’s scheduler supports only three frequency options (not full cron syntax): every 10 minutes, hourly, or daily. For more complex schedules, you need a third-party add-on.

Common Cron Mistakes

Off-by-One on Day of Week

Different implementations number days of the week differently. Linux cron: Sunday = 0 or 7, Monday = 1. Quartz: Sunday = 1, Saturday = 7. Always verify using a cron validator before deploying.

UTC vs Local Time Confusion

Most cron environments run in UTC. If you want a job at β€œ9 AM local time” and your server is in UTC+8, you need to schedule it at 0 1 * * * (1 AM UTC). Forgetting this leads to jobs running at wrong hours, especially around daylight saving time transitions.

Missing Absolute Paths

# WRONG β€” cron has minimal PATH, 'node' may not be found
0 2 * * * node /app/scripts/report.js

# CORRECT β€” use absolute path
0 2 * * * /usr/local/bin/node /app/scripts/report.js

# Also correct β€” set PATH in crontab header
PATH=/usr/local/bin:/usr/bin:/bin
0 2 * * * node /app/scripts/report.js

Concurrent Job Accumulation

If your job takes longer than its schedule interval, you’ll get multiple instances running simultaneously, potentially causing race conditions, resource exhaustion, or data corruption.

Solutions:

  • Use a lock file: flock -n /tmp/myjob.lock /usr/local/bin/myjob.sh
  • Use chronic from moreutils to suppress output unless there’s an error
  • For Kubernetes, set concurrencyPolicy: Forbid

Swallowed Errors

# WRONG β€” errors are silently discarded
0 2 * * * /usr/local/bin/backup.sh > /dev/null 2>&1

# BETTER β€” log both stdout and stderr
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# BEST β€” use chronic to only email/log on error
0 2 * * * chronic /usr/local/bin/backup.sh

Day-of-Month AND Day-of-Week

When both fields are specified (not *), cron runs the job when either condition is true β€” not both:

# WRONG if you want "first Monday of the month"
# This runs on the 1st of every month AND every Monday
0 9 1 * 1

# CORRECT approach β€” check in the script itself
0 9 1-7 * 1  # Run on Mon within first 7 days, then check in script

Cron Expression Validation

Before deploying a cron expression, validate it to confirm it behaves as expected. The key questions:

  1. When will it first run?
  2. What are the next 5-10 execution times?
  3. Does it run at the right frequency?
  4. Does it handle month-end edge cases correctly?

Validating manually is error-prone. Use a generator/validator to see the next N execution times and confirm they match your intent.

FAQ

Q: What’s the difference between */5 and 0/5?

In standard cron, they’re equivalent β€” both mean β€œevery 5 units starting from 0.” In some implementations, 0/5 is more explicit about the starting point, while */5 means β€œevery 5th value of the full range.” For practical purposes, they produce identical results for the minute and hour fields.

Q: How do I run a job every 30 seconds?

Standard cron doesn’t support sub-minute scheduling. The workaround is two cron jobs with a 30-second sleep in the second:

* * * * * /usr/local/bin/myjob.sh
* * * * * sleep 30 && /usr/local/bin/myjob.sh

For true sub-minute scheduling, consider systemd timers, a task queue (Celery, Sidekiq), or a purpose-built scheduler.

Q: How do I schedule a job for the last day of the month?

Standard cron can’t directly express β€œlast day of month” in a portable way. The most common solution:

# Run on 28th-31st and check if tomorrow is the 1st
0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /usr/local/bin/end_of_month.sh

Quartz cron supports the L character for this: 0 23 L * ?

Q: Are cron expressions the same everywhere?

No β€” this is a constant source of confusion. The standard 5-field cron syntax is widely supported, but extensions vary:

  • Quartz (Java): 6 fields with seconds, plus L, W, #, ?
  • AWS EventBridge: 6 fields with year, different day-of-week handling
  • Jenkins: supports H for β€œhash” to distribute jobs
  • Some systems: @reboot, @daily, @weekly shortcuts

Always check the docs for the specific platform you’re using.

Q: What does @reboot mean?

@reboot is a cron shorthand that runs a command once when the cron daemon starts (typically at system boot). Other shorthands: @hourly, @daily, @weekly, @monthly, @yearly.


Build Your Cron Expression in Seconds

Staring at five blank fields trying to remember whether day-of-week goes in the 5th or 6th position? Stop guessing. The DevPlaybook Cron Expression Generator lets you build cron expressions interactively and see the next 10 execution times instantly β€” so you can confirm your schedule is exactly right before deploying.

Select your frequency, adjust the fields, and the expression updates in real time. No memorization required, no risk of deploying a job that runs every minute when you meant every hour.

Open Cron Expression Generator β†’

Whether you’re scheduling a Kubernetes CronJob, a GitHub Actions workflow, a Linux crontab entry, or an AWS EventBridge rule, get the expression right the first time.

Free Download

50 CLI Commands That Save Hours Every Week

The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.

  • Git mastery (10 cmds)
  • File & search wizardry
  • Docker & DevOps tricks
  • Process & network tools
  • Productivity boosters
  • macOS & Linux install guide

No spam. 1 email/week max. Unsubscribe anytime.

Found this guide useful? Check out our free developer tools.