What Is a Cron Expression?
A cron expression is a compact scheduling syntax originally created for the Unix cron daemon, the default job scheduler on Linux and macOS. Each expression encodes a repeating point in time — when should this job fire? — using five fields separated by spaces: minute, hour, day of month, month, and day of week. The daemon reads a user’s crontab file and executes the corresponding command whenever the system clock matches the pattern.
Cron expressions have since spread far beyond Unix. Kubernetes CronJobs, AWS EventBridge, GitHub Actions, Jenkins, Airflow, Spring @Scheduled, and Cloudflare Workers Cron Triggers all use the same core syntax (with minor extensions). If you learn the five-field format once, you can schedule jobs across nearly every platform.
How to Use This Cron Expression Builder
- Enter an expression directly in the input field — for example
0 9 * * 1-5— and the tool instantly shows a human-readable description, the next scheduled run times, and a breakdown of each field. - Or use the visual builder — select values for minute, hour, day, month, and weekday using the dropdowns. The expression is assembled and validated as you go.
- Read the next-run preview to confirm the schedule matches your intent before pasting it into your crontab, CI config, or orchestrator.
Everything runs client-side. No backend, no signup, no data leaves your machine.
Cron Expression Format
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12 or JAN-DEC)
│ │ │ │ ┌───────────── day of week (0-7 or SUN-SAT, 0 and 7 = Sunday)
│ │ │ │ │
* * * * *
Each field accepts a single value, a range, a list, a step, or a wildcard — or a combination of these.
Special Characters
| Character | Meaning | Example | Description |
|---|---|---|---|
* | Any value | * * * * * | Every minute |
, | List | 1,15 * * * * | At minute 1 and minute 15 |
- | Range | 9-17 * * * * | Every minute from 9:00 through 17:59 |
/ | Step | */10 * * * * | Every 10 minutes starting at :00 |
L | Last (day) | 0 0 L * * | Last day of the month (non-standard) |
W | Nearest weekday | 0 0 15W * * | Nearest weekday to the 15th (non-standard) |
# | Nth weekday | 0 0 * * 5#3 | Third Friday of the month (non-standard) |
The L, W, and # operators are extensions supported by Quartz, Spring, and some cloud schedulers. Standard Unix cron does not recognize them.
Common Cron Expressions
| Expression | Description |
|---|---|
* * * * * | Every minute |
0 * * * * | Every hour at :00 |
0 0 * * * | Daily at midnight |
0 0 * * 0 | Every Sunday at midnight |
0 0 1 * * | First day of every month at midnight |
*/5 * * * * | Every 5 minutes |
*/15 * * * * | Every 15 minutes (:00, :15, :30, :45) |
*/30 * * * * | Every 30 minutes (:00 and :30) |
0 9-17 * * 1-5 | Every hour from 9 AM to 5 PM, weekdays |
30 2 * * * | Daily at 2:30 AM |
0 0,12 * * * | Twice a day, at midnight and noon |
0 0 1,15 * * | 1st and 15th of every month at midnight |
0 */6 * * * | Every 6 hours (midnight, 6 AM, noon, 6 PM) |
0 0 * * 1-5 | Every weekday at midnight |
0 0 * * 0,6 | Every weekend day (Saturday and Sunday) |
0 0 * * 1,3,5 | Every Monday, Wednesday, and Friday |
0 8 * * 1 | Every Monday at 8 AM |
0 0 1 1,4,7,10 * | First day of each quarter at midnight |
Cron Shorthand Aliases
Standard Unix and Linux cron accept a handful of @-prefixed shortcuts in place of the five fields. They make common schedules easier to read at a glance:
| Alias | Equivalent | Meaning |
|---|---|---|
@yearly / @annually | 0 0 1 1 * | Once a year, at midnight on January 1 |
@monthly | 0 0 1 * * | Once a month, at midnight on the 1st |
@weekly | 0 0 * * 0 | Once a week, at midnight on Sunday |
@daily / @midnight | 0 0 * * * | Once a day, at midnight |
@hourly | 0 * * * * | Once an hour, at the top of the hour |
@reboot | — | Once, each time the system boots |
@reboot is the odd one out: it has no clock equivalent because it fires on startup rather than at a fixed time. These aliases are convenient, but they are not universal — GitHub Actions, AWS EventBridge, and many cloud schedulers reject them, so stick to the explicit five-field form when portability matters.
Cron Across Platforms
The five-field format is universal, but platforms extend it in different ways:
Linux / macOS crontab — the original five-field format. Supports @reboot, @hourly, @daily, @weekly, @monthly, and @yearly shorthand aliases. The timezone is the system timezone unless you set TZ= in the crontab.
AWS EventBridge (CloudWatch Events) — uses six fields: minute hour day-of-month month day-of-week year. The year field accepts * or a range like 2026-2028. Also supports rate(5 minutes) syntax for simple intervals.
Kubernetes CronJobs — standard five-field format. The timezone defaults to the kube-controller-manager timezone (usually UTC). Since Kubernetes 1.27 you can set .spec.timeZone explicitly.
GitHub Actions — five-field cron in the schedule trigger. Runs in UTC only — there is no timezone override. Schedules may be delayed under heavy load; they are best-effort, not guaranteed-precise.
Spring / Quartz (Java) — six fields with a seconds column prepended: second minute hour day month weekday. Supports L, W, #, and ? operators for more expressive scheduling.
Managing Your Crontab
On Linux and macOS, each user has their own crontab file, edited through the crontab command rather than by opening the file directly:
| Command | What it does |
|---|---|
crontab -e | Open your crontab in the default editor |
crontab -l | Print your current cron jobs to the terminal |
crontab -r | Delete your entire crontab (no confirmation!) |
crontab -u alice -e | Edit another user’s crontab (needs root) |
Because -r sits next to -e on the keyboard and asks for no confirmation, accidentally wiping a crontab is a classic mistake — back it up first with crontab -l > my-crontab.bak. To disable one job without deleting it, comment out its line with a leading #.
Beyond per-user crontabs, the system has global schedules in /etc/crontab and drop-in files under /etc/cron.d/. Note that these system files add a user column between the day-of-week field and the command, specifying which account runs the job. User crontabs do not have that column.
Debugging: Why Isn’t My Cron Job Running?
When a job silently fails, work through this checklist:
- Use absolute paths. Cron runs with a minimal environment and a bare
PATH(typically/usr/bin:/bin). A command that works in your shell may not be found by cron. Use full paths like/usr/local/bin/nodeand reference scripts by their absolute location. - Capture the output. By default cron emails a job’s output to the local user, which usually goes nowhere. Redirect it to a log instead:
* * * * * /path/script.sh >> /var/log/myjob.log 2>&1. The2>&1captures errors too. - Check the cron log. On Debian/Ubuntu run
grep CRON /var/log/syslog; on RHEL/CentOS check/var/log/cron. If the job never appears there, cron never triggered it — recheck the expression. - Verify permissions. The script must be executable (
chmod +x script.sh) and start with a correct shebang line such as#!/bin/bash. - End the file with a newline. Some cron implementations ignore the last line of a crontab if it has no trailing newline.
crontab -enormally handles this, but hand-edited files can trip on it.
Common Cron Mistakes and How to Fix Them
Timezone confusion. The single most common cron problem. Your server runs in UTC, you write 0 9 * * * thinking “9 AM my time,” and the job fires at the wrong hour. Always verify the timezone of the cron daemon. On Linux, run timedatectl or check /etc/timezone.
Day-of-month vs. day-of-week conflict. In standard cron, if you set both the day-of-month and day-of-week fields (neither is *), the job fires when either condition is true — it’s an OR, not an AND. 0 0 15 * 5 means “midnight on the 15th OR any Friday,” not “midnight on the 15th if it’s a Friday.” Some platforms (Quartz) use ? in one field to avoid this ambiguity.
Off-by-one in day-of-week. Sunday is 0 (or 7) in standard cron, but some systems use 1 for Monday and 7 for Sunday. Double-check your platform’s documentation if your weekend jobs fire on the wrong day.
Forgetting that */n starts from 0, not from now. */10 in the minute field fires at :00, :10, :20, :30, :40, :50 — not “every 10 minutes starting from when I saved the crontab.” If you add the entry at 9:03, the first run is still at 9:10.
Overlapping runs. If a job takes longer than its interval, cron starts a second instance. Use flock on Linux (flock -n /tmp/myjob.lock command) to prevent overlap, or set concurrency limits in your orchestrator.
Cron Builder vs. Other Tools
- This tool — zero-signup, instant validation with human-readable output and next-run preview. Privacy-first: nothing leaves your browser. Best for quickly building or debugging a cron expression.
- crontab.guru — focused expression explainer with a clean UI. Shows a plain-English translation and highlighted next-run dates. No visual builder for constructing expressions.
- Cron Maker — generates expressions through a form-based UI. Useful if you prefer clicking over typing, but supports fewer platform extensions.
- Your terminal —
crontab -eedits your live crontab directly. Fastest when you already know the syntax, but no validation or preview before saving.
Use this tool when you need to build an expression from scratch or verify one before deploying it.