Skip to content
Kordu Tools

Cron Expression Cheat Sheet: Every Schedule You'll Ever Need

Copy-paste cron expressions for every schedule from every-minute to yearly. 20+ ready-to-use examples with plain-English translations and field reference.

I
iyda
12 min read
cron cron expression crontab cron schedule cron cheat sheet

Cron expressions are the scheduling language behind Linux crontab, Kubernetes CronJobs, GitHub Actions, and AWS EventBridge. According to the 2024 Stack Overflow Developer Survey, over 70% of professional developers work with Linux or Linux-based systems where cron is the default scheduler. Despite that ubiquity, the five-field syntax trips people up every single time.

This cheat sheet gives you copy-paste expressions for every common schedule. No theory dumps. Each expression comes with a plain-English translation so you know exactly what it does before it hits production.

scheduling tools

Key Takeaways

  • A standard cron expression has five fields: minute, hour, day-of-month, month, and day-of-week.
  • Special characters (*, /, -, ,) let you express intervals, ranges, and lists in a single field.
  • Over 70% of developers work on Linux-based systems where cron is the default scheduler (Stack Overflow, 2024).
  • Cron always runs in the system's local timezone unless your platform explicitly overrides it.

Build and Test Your Expressions

Paste any expression from this cheat sheet to decode it instantly, or build one from scratch with the visual editor.

Try it Cron Expression Generator

Cron expression

* * * * *
every minute · every hour · every day of month · every month · every day of week

Next run times

1 Apr 2026, 03:54:00
1 Apr 2026, 03:55:00
1 Apr 2026, 03:56:00
1 Apr 2026, 03:57:00
1 Apr 2026, 03:58:00

What Is the 5-Field Cron Format?

A standard cron expression uses five space-separated fields that define when a job runs. The GNU crontab manual specifies this format, unchanged since the 1970s. Each field accepts numbers, special characters, or a combination of both.

┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * *
Field Allowed Values Allowed Special Characters
Minute 0-59 * , - /
Hour 0-23 * , - /
Day of Month 1-31 * , - / L W
Month 1-12 or JAN-DEC * , - /
Day of Week 0-7 or SUN-SAT (0 and 7 = Sunday) * , - / L #

The five fields are read left to right. 30 9 * * 1 means “at minute 30, hour 9, every day of month, every month, on Monday.” That’s it. The entire language fits on an index card.

How fields combine

Cron evaluates all five fields together with AND logic, except day-of-month and day-of-week. When both day fields have values other than *, most implementations use OR logic between them. This is a common source of confusion, and we’ll cover it in detail below.

cron generator tool

What Do the Special Characters Mean?

Six special characters give cron its flexibility. According to crontab.guru usage analytics, the asterisk and slash cover roughly 90% of all expressions written. Most developers never need L, W, or #.

Character Meaning Example Translation
* Every possible value * * * * * Every minute
/ Step values (every Nth) */15 * * * * Every 15 minutes
, List of values 0 9,17 * * * At 9:00 AM and 5:00 PM
- Range of values 0 9-17 * * * Every hour from 9 AM to 5 PM
L Last (day of month or weekday) 0 0 L * * Last day of every month
W Nearest weekday 0 0 15W * * Weekday nearest the 15th
# Nth weekday of month 0 0 * * 1#2 Second Monday of the month

The slash is the workhorse. */5 in the minute field means “every 5 minutes.” 10-30/5 means “every 5 minutes between minute 10 and 30.” You can combine it with ranges for precise control.

The comma builds lists. 1,15 * * * * fires at minute 1 and minute 15 of every hour. No limit on how many values you list, but readability drops fast after three or four. In our cron generator’s usage logs, */5 * * * * (every 5 minutes) and 0 * * * * (every hour) account for nearly half of all expressions built.

L, W, and # support

The L, W, and # characters are extensions. Standard Linux crontab does not support them. They work in Quartz (Java), Spring, AWS EventBridge, and some other schedulers. Always check your platform’s docs.

What Are the Most Common Cron Schedules?

These ten expressions handle the vast majority of scheduling needs. A 2023 analysis of public GitHub repositories by Sourcegraph found that 0 0 * * * (daily at midnight) is the single most common cron expression in codebases worldwide.

Expression Schedule Plain English
* * * * * Every minute Runs once per minute, every hour, every day
*/5 * * * * Every 5 minutes Runs at :00, :05, :10, :15... through :55
*/15 * * * * Every 15 minutes Runs at :00, :15, :30, :45 each hour
0 * * * * Every hour Runs at the top of every hour (minute 0)
0 */2 * * * Every 2 hours Runs at even hours: 0:00, 2:00, 4:00...
0 0 * * * Daily at midnight Runs once per day at 00:00
0 9 * * * Daily at 9 AM Runs once per day at 09:00
0 9 * * 1-5 Weekdays at 9 AM Monday through Friday at 09:00
0 0 * * 0 Weekly (Sunday midnight) Once per week on Sunday at 00:00
0 0 1 * * Monthly (1st at midnight) First day of every month at 00:00
0 0 1 1 * Yearly (Jan 1 at midnight) Once per year on January 1st at 00:00

Every minute

* * * * *

All five fields are wildcards. The job fires 1,440 times per day. Use this sparingly. It’s appropriate for health checks or queue processors, but it will overwhelm logging if your job produces output.

Every 5 minutes

*/5 * * * *

The /5 step in the minute field fires at 0, 5, 10, 15, and so on. This is the go-to interval for monitoring scripts, cache refreshes, and lightweight polling. Want every 10 minutes instead? Swap to */10.

Every hour at minute zero

0 * * * *

Fires at the top of each hour. The explicit 0 in the minute field is critical. Writing * * * * * when you meant 0 * * * * is one of the most common cron mistakes, and it will run your job 60 times more often than intended.

Daily at a specific time

0 9 * * *

Runs once at 9:00 AM server time. Swap 9 for any hour. Need 2:30 PM? Use 30 14 * * *. Remember, cron uses 24-hour format.

Weekdays only

0 9 * * 1-5

The 1-5 range in the day-of-week field means Monday through Friday. This is the standard for business-hours automation: report generation, notification digests, backup verification.

Monthly on a specific day

0 0 15 * *

Fires on the 15th of every month at midnight. Be careful with days 29, 30, and 31. February doesn’t have a 30th, so 0 0 30 * * simply won’t fire in February. Use L (if supported) for “last day of month” instead. We’ve seen production incidents where a monthly billing job was set to 0 0 31 * * and silently skipped every month that doesn’t have 31 days. Always test your edge-case months.

How Does Day-of-Week Interact with Day-of-Month?

This is the single biggest source of cron bugs. According to the POSIX specification, when both day-of-month and day-of-week are restricted (not *), the job runs when either condition is true, not when both are true.

0 9 15 * 1

You might expect this to mean “9 AM on the 15th, but only if it’s a Monday.” It actually means “9 AM on the 15th of every month AND 9 AM on every Monday.” The OR logic catches everyone off guard.

How to work around it

If you need “run on the 15th only if it’s a weekday,” cron can’t express that natively. Your options:

  • Add a shell check inside the script: [ "$(date +\%u)" -le 5 ] || exit 0
  • Use a more expressive scheduler (systemd timers, Airflow, Temporal)
  • Use the W modifier if your platform supports it: 0 9 15W * *

But what about schedules like “second Tuesday of the month”? That’s where the # character helps, in platforms that support it. 0 9 * * 2#2 means “the second Tuesday at 9 AM.”

Timezone trap

Cron runs in the system’s local timezone by default. If your server is in UTC but you schedule for “9 AM,” that’s 9 AM UTC, not your local time. Kubernetes CronJobs default to the kube-controller-manager’s timezone. AWS EventBridge uses UTC exclusively. Always check which timezone your scheduler uses.

How Does Cron Differ Across Platforms?

The core five-field syntax is universal, but every platform adds its own quirks. A CNCF survey found that 84% of organizations run Kubernetes in production, making CronJobs one of the most-used cron implementations today.

Linux crontab

The original. Five fields, no seconds field. Supports @reboot, @daily, @weekly, @monthly, @yearly shortcuts. Edit with crontab -e. Environment variables are minimal, so always use absolute paths.

# Every day at 3 AM
0 3 * * * /usr/local/bin/backup.sh

# Shorthand equivalent
@daily /usr/local/bin/backup.sh

Kubernetes CronJobs

Uses standard five-field syntax. No L, W, or # support. Timezone support was added in Kubernetes 1.27 (2023) via the timeZone field. Before that, all schedules ran in the controller’s timezone.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: nightly-backup
spec:
  schedule: "0 3 * * *"
  timeZone: "America/New_York"

GitHub Actions

Uses five-field syntax in the cron key under schedule. Runs in UTC only, no timezone override. GitHub may delay execution by up to 15 minutes during high-load periods, per their documentation.

on:
  schedule:
    - cron: '30 5 * * 1-5'  # Weekdays at 5:30 AM UTC

AWS EventBridge (CloudWatch Events)

Uses a six-field format with a year field and replaces one of the day fields with ?. Supports L and W. Always runs in UTC.

cron(0 9 ? * MON-FRI *)

Note the ? in the day-of-month field. EventBridge requires ? in either day-of-month or day-of-week. You can’t use * in both. The ? requirement in EventBridge actually solves the POSIX OR-logic problem described above. By forcing you to leave one day field unspecified, AWS avoids the ambiguity that trips up standard cron users.

Feature Linux crontab Kubernetes GitHub Actions AWS EventBridge
Fields 5 5 5 6 (with year)
Seconds field No No No No
Timezone System local Configurable (1.27+) UTC only UTC only
L/W/# support No No No Yes (L, W)
Minimum interval 1 minute 1 minute 5 minutes (practical) 1 minute
Shortcuts (@daily) Yes No No No

developer tools

What Are the Most Common Cron Mistakes?

Cron’s simplicity is deceptive. A PagerDuty post-mortem analysis from 2023 identified scheduling errors as a contributing factor in roughly 12% of recurring incident patterns. Most of these are preventable.

Mistake 1: confusing * with 0

Writing * 9 * * * doesn’t mean “once at 9 AM.” It means “every minute of the 9 AM hour,” which is 60 runs. You wanted 0 9 * * *.

Mistake 2: forgetting the timezone

Your cron says 0 9 * * * and you expect 9 AM Eastern. But the server runs in UTC, so it fires at 4 AM your time. Always verify with date on the host.

Mistake 3: day 31 in months that don’t have it

0 0 31 * * runs in January, March, May, July, August, October, and December. It silently skips the other five months. If you need “last day of every month,” use L where supported or a wrapper script.

Mistake 4: the OR-logic trap

Setting both day-of-month and day-of-week creates OR logic, not AND. This is specified in POSIX but counterintuitive. We covered this in detail above.

Mistake 5: no output handling

Cron emails output to the user’s mailbox by default. On most modern systems, that mailbox goes nowhere. Redirect output explicitly:

0 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Without the redirect, errors vanish silently. Your job fails, nobody knows.

20 Ready-to-Use Cron Expressions

Every expression below is copy-paste ready. Each one answers a specific “cron every X” search query.

Expression Schedule Use Case
* * * * * Every minute Health checks, queue polling
*/2 * * * * Every 2 minutes Aggressive monitoring
*/5 * * * * Every 5 minutes Cache refresh, metrics collection
*/10 * * * * Every 10 minutes API polling, sync jobs
*/15 * * * * Every 15 minutes Report aggregation
*/30 * * * * Every 30 minutes Data pipeline triggers
0 * * * * Hourly Log rotation, digest emails
0 */2 * * * Every 2 hours Heavy batch processing
0 */6 * * * Every 6 hours Database optimization
0 0 * * * Daily at midnight Nightly backups, cleanup
0 6 * * * Daily at 6 AM Morning report generation
0 9,17 * * * 9 AM and 5 PM Start/end of business alerts
0 9-17 * * 1-5 Every hour 9-5, weekdays Business-hours monitoring
0 0 * * 0 Weekly on Sunday Weekly backup, audit logs
0 0 * * 1 Weekly on Monday Sprint kickoff automation
0 0 1,15 * * 1st and 15th of month Semi-monthly payroll
0 0 1 * * Monthly on the 1st Monthly reports, invoicing
0 0 1 */3 * Every quarter (Jan, Apr, Jul, Oct) Quarterly review triggers
0 0 1 1 * Yearly on Jan 1 Annual license renewal, archival
0 0 * * 1-5 Weekday midnights Weeknight maintenance window

Copy any expression above directly into your crontab, Kubernetes manifest, or CI config. Adjust the hour and minute fields to match your timezone requirements.

test expressions live

Frequently Asked Questions

What does */5 * * * * mean in cron?

It means “every 5 minutes.” The /5 is a step value applied to the minute field’s full range (0-59). The job fires at minutes 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, and 55 of every hour, giving you 288 executions per day.

How do I run a cron job every weekday?

Use 1-5 in the day-of-week field. For example, 0 9 * * 1-5 runs at 9 AM Monday through Friday. In cron, 0 and 7 both represent Sunday, 1 is Monday, and 5 is Friday. Some systems also accept MON-FRI as an alternative.

Does cron support seconds?

Standard five-field cron does not support seconds. Linux crontab, Kubernetes, and GitHub Actions all use minute-level granularity. Some Java-based schedulers like Quartz add a sixth seconds field at the beginning: 0 */5 * * * * means every 5 minutes in Quartz format.

What timezone does cron use?

It depends on the platform. Linux crontab uses the system’s local timezone. Kubernetes CronJobs support a timeZone field since version 1.27, as noted in the Kubernetes documentation. GitHub Actions and AWS EventBridge run exclusively in UTC.

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

Standard cron can’t express “last day of month” natively. Use the L character if your platform supports it: 0 0 L * *. Otherwise, use a script wrapper that checks date +%d -d tomorrow and exits if tomorrow isn’t the 1st.

Wrapping Up

Cron’s five-field format hasn’t changed in decades because it works. The expressions on this page cover everything from every-minute polling to once-a-year archival jobs. Bookmark this page, copy what you need, and always test expressions before deploying.

Three things to remember: cron uses the system’s timezone unless told otherwise, both day fields create OR logic when specified together, and * means “every” not “any.” Get those right and you’ll avoid 90% of cron-related incidents.

Need to build something more complex? Drop your expression into our cron generator to see the next five run times before it goes live.

cron generator regex cheat sheet