Cron Expression Generator Guide — Complete Tutorial with Examples

By Risetop Team · 14 min read · Updated April 2026

Cron expressions are the backbone of automated task scheduling on Unix-like systems, and they have become a standard across cloud platforms, programming languages, and CI/CD pipelines worldwide. Whether you are setting up a nightly database backup, scheduling a daily report email, or configuring a recurring API health check, cron expressions are the language you need to speak. This guide covers everything from basic syntax to advanced patterns, with real-world examples you can copy and use immediately.

What Is a Cron Expression?

A cron expression is a string of five or six fields separated by spaces that defines a schedule for recurring tasks. Originally part of the Unix cron daemon (short for "chronograph"), the format has been adopted by Java's Quartz scheduler, Kubernetes CronJobs, AWS EventBridge, GitHub Actions, and countless other platforms. Despite minor variations between implementations, the core syntax remains consistent across virtually all systems.

The standard Unix cron expression has five fields representing different units of time:

* * * * *
FieldAllowed ValuesDescription
Minute0-59The exact minute of the hour
Hour0-23The hour of the day (24-hour format)
Day of Month1-31The day of the month
Month1-12 (or JAN-DEC)The month of the year
Day of Week0-7 (or SUN-SAT, 0 and 7 = Sunday)The day of the week

Some implementations add optional fields. The most common extension is a sixth field at the beginning for seconds (used by Quartz, AWS, and many cloud schedulers), or a sixth field at the end for the year (also Quartz). We will note these variations as they come up.

Understanding Cron Syntax: Operators and Special Characters

The power of cron expressions comes from a small set of operators that you combine within each field. Master these five operators and you can express virtually any schedule:

Asterisk (*) — Every Value

The asterisk matches every possible value for the field. */5 * * * * means "every 5 minutes" because the asterisk in the minute field combined with the step operator selects every fifth minute. Used alone, * means "every" — every minute, every hour, every day.

Comma (,) — List of Values

Separate specific values with commas to create a list. 0 9,12,18 * * * runs a task at 9:00 AM, 12:00 PM, and 6:00 PM every day. You can mix numbers and abbreviated names: 0 9 * * MON,FRI runs at 9:00 AM every Monday and Friday.

Hyphen (-) — Range of Values

Define a range with a hyphen. 0 9-17 * * * runs every hour from 9:00 AM to 5:00 PM. Ranges are inclusive on both ends. You can combine ranges with lists: 0 9-11,13-17 * * * runs from 9-11 AM and 1-5 PM.

Slash (/) — Step Values

The slash specifies step increments within a range. */15 * * * * runs every 15 minutes (0, 15, 30, 45). 0-30/10 * * * * runs every 10 minutes, but only during the first 30 minutes of each hour (0, 10, 20, 30). The value before the slash is the start; if omitted, it defaults to the field's minimum value.

Special Strings

Unix cron provides several shorthand strings that replace full expressions:

StringEquivalentMeaning
@yearly (or @annually)0 0 1 1 *Once a year, January 1st at midnight
@monthly0 0 1 * *Once a month, on the 1st at midnight
@weekly0 0 * * 0Once a week, Sunday at midnight
@daily (or @midnight)0 0 * * *Once a day, midnight
@hourly0 * * * *Once an hour, at minute 0
@rebootN/ARun once at system startup

These shortcuts are supported on most Unix systems but may not work in cloud cron implementations like AWS or Kubernetes. When in doubt, use the full expression.

Real-World Cron Expression Examples

Here is a comprehensive collection of cron expressions for common scheduling scenarios. Copy and adapt these for your own use cases:

Basic Schedules

# Every minute
* * * * *

# Every 5 minutes
*/5 * * * *

# Every 30 minutes
*/30 * * * *

# Every hour at minute 0
0 * * * *

# Every 2 hours
0 */2 * * *

# Every 6 hours
0 */6 * * *

Daily Schedules

# Daily at midnight
0 0 * * *

# Daily at 6:30 AM
30 6 * * *

# Daily at 9 AM and 5 PM
0 9,17 * * *

# Every weekday (Mon-Fri) at 9 AM
0 9 * * 1-5

# Weekends only at 10 AM
0 10 * * 0,6

Weekly and Monthly Schedules

Complex Patterns

# Every weekday every 5 minutes during business hours
*/5 9-17 * * 1-5

# Every Sunday at 2:30 AM
30 2 * * 0

# Every January and July at midnight
0 0 * 1,7 *

# Twice daily: 8 AM and 8 PM
0 8,20 * * *

# Every 10 minutes between 9 AM and 5 PM on weekdays
*/10 9-17 * * 1-5
Remember: In Unix crontab, the day-of-week field (0-7) and the day-of-month field are ORed together, not ANDed. If you specify both a day-of-month and a day-of-week, the task runs when either condition is met. This is a common source of unexpected behavior.

Setting Up Cron Jobs: Practical Guide

Now that you understand the syntax, here is how to actually put cron expressions to work on a real system.

Editing Your Crontab

On any Unix-like system, open your user's crontab by running:

crontab -e

This opens the crontab file in your default editor. Each line is a separate cron job in the format:

* * * * * /path/to/command arg1 arg2

For example, to run a Python backup script every night at 2 AM:

0 2 * * * /usr/bin/python3 /home/user/scripts/backup.py >> /home/user/logs/backup.log 2>&1

Environment Variables in Crontab

Cron jobs run in a minimal environment — they do not inherit your shell's PATH, environment variables, or aliases. This is the number one reason cron jobs fail silently. Always use absolute paths for commands and scripts, and explicitly set any environment variables your script needs.

# Set environment at the top of your crontab
PATH=/usr/local/bin:/usr/bin:/bin
PYTHONPATH=/home/user/myproject
NODE_ENV=production

# Then your jobs
0 2 * * * python3 /home/user/scripts/backup.py
0 * * * * node /home/user/app/health-check.js

Logging and Debugging

Cron sends any output from your commands to your local mailbox by default. To capture logs to a file, redirect both stdout and stderr:

0 2 * * * /home/user/scripts/backup.sh >> /var/log/backup.log 2>&1

To check whether your cron jobs are running, inspect the system cron log:

# On Ubuntu/Debian
grep CRON /var/log/syslog

# On CentOS/RHEL
grep CROND /var/log/cron

# List all cron jobs for your user
crontab -l

Cron Expressions in Cloud Platforms and Frameworks

While Unix cron is the origin, cron expressions are now used across many platforms with slight variations. Here is what you need to know about the most popular implementations:

Quartz Scheduler (Java)

Quartz uses a six-field format with seconds as the first field and an optional year as the seventh:

Seconds Minutes Hours DayOfMonth Month DayOfWeek [Year]
0 0 12 * * ?       # Every day at noon
0 0/5 14 * * ?     # Every 5 minutes from 2-3 PM

Key difference: Quartz uses ? (instead of *) for the day-of-month or day-of-week field when you want to ignore one of them. You cannot use * in both fields simultaneously — one must be ?.

Kubernetes CronJobs

Kubernetes uses the standard five-field format but requires the ConcurrencyPolicy and StartingDeadlineSeconds configurations alongside the schedule:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: daily-report
spec:
  schedule: "0 8 * * *"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: report
            image: myapp:latest
          restartPolicy: OnFailure

AWS EventBridge (CloudWatch Events)

AWS uses a six-field format with seconds at the beginning and optionally years at the end:

cron(0 10 * * ? *)      # Every day at 10:00 AM UTC
cron(0/15 * * * ? *)  # Every 15 minutes
cron(0 9 ? * 2-6 *)    # Weekdays at 9 AM UTC

Important: AWS cron always requires the ? for either day-of-month or day-of-week, and the year field is mandatory (use * for every year). Also note that AWS cron evaluates in UTC unless you specify a timezone.

GitHub Actions

GitHub Actions uses a simplified cron syntax with five fields and supports ranges, steps, and asterisks:

on:
  schedule:
    - cron: '0 0 * * *'  # Daily at midnight UTC

Common Mistakes and How to Avoid Them

Security Note: Never put passwords, API keys, or sensitive data directly in cron commands where they would be visible via ps aux or in system logs. Use environment files, secrets management tools, or config files with restricted permissions instead.

Tips for Writing Readable Cron Expressions

Cron expressions can be cryptic, especially for complex schedules. Here are practices that make them more maintainable:

  1. Add comments above each cron job explaining what it does and why it runs on that schedule.
  2. Use meaningful script names rather than inline commands. 0 2 * * * /opt/scripts/nightly-db-backup.sh is clearer than a long one-liner.
  3. Group related jobs together in your crontab with section headers.
  4. Test with a dry run before deploying. Use tools like crontab.guru to verify your expression means what you think it means.
  5. Keep a backup of your crontab before making changes: crontab -l > crontab-backup.txt.

Frequently Asked Questions

What is the difference between cron and systemd timers?

Systemd timers are the modern alternative to cron on Linux systems that use systemd. They offer advantages like dependency management, logging integration with journald, and support for monotonic timers (e.g., "10 minutes after boot"). However, cron remains more universally supported and is simpler for basic schedules. Many systems use both — cron for user-level tasks and systemd timers for system services.

Can I run a cron job every second?

Standard Unix cron has a minimum resolution of one minute — it cannot run tasks every second. For sub-minute scheduling, use a while loop in a script, systemd timers with AccuracySec, or a dedicated scheduler like Quartz (Java) or APScheduler (Python). Be cautious with second-level scheduling, as it can create significant system load if the task is resource-intensive.

Why is my cron job not running?

The most common reasons: (1) The PATH is wrong — use absolute paths for all commands. (2) The script lacks execute permissions — run chmod +x script.sh. (3) The cron daemon is not running — check with systemctl status cron. (4) There is a syntax error in the expression — validate with an online tool. (5) The user does not have permission — check /etc/cron.allow and /etc/cron.deny.

How do I handle daylight saving time changes in cron?

Standard cron does not account for DST. Jobs scheduled for 2:30 AM may run once, twice, or not at all during a DST transition depending on the direction of the change. For critical scheduling, use UTC-based scheduling (which has no DST) and convert to local time in your script if needed, or use a library like pytz or moment-timezone in application-level schedulers.

What does the ? character mean in Quartz cron expressions?

In Quartz scheduler, ? means "no specific value" and is used exclusively in the day-of-month or day-of-week field. You must use ? in one of these two fields (not both) because Quartz requires you to explicitly indicate which day field you are not specifying. This is different from standard Unix cron, where * serves this purpose.

How can I test a cron expression without waiting for it to trigger?

Use online validators like crontab.guru to verify the expression describes the schedule you expect. To test the actual command, run it manually in your shell first. For a more thorough test, temporarily set the cron schedule to run every minute (* * * * *), verify it works, then change it back to the intended schedule.

Cron expressions are one of the most widely used scheduling mechanisms in computing, and understanding them thoroughly pays dividends across every layer of the technology stack. From a simple crontab on a single server to complex cloud-native scheduling pipelines, the syntax and principles remain the same. Bookmark this guide, practice with the examples, and you will never struggle with cron scheduling again.