Cron Expression Cheat Sheet: Syntax, Examples & Online Tester

By Hari Prakash · 2026-02-22 · 5 min read

A cron expression is five characters away from being perfectly readable — and five characters away from scheduling your backup script to run every second instead of every Sunday. Cron is the standard job scheduler on Linux and Unix systems, and its expression syntax is something most developers memorize through trial and error rather than intention. That's how you end up with a production cron job that fires 1,440 times a day instead of once.

This cheat sheet breaks down cron expression syntax into a reference you can actually use. Every example below is copy-paste ready. If you want to validate your expressions before deploying them, the PinusX Cron Expression Parser shows the next execution times in plain English so you can confirm the schedule does what you think it does — all processed in your browser, no server involved.

Cron Syntax: The Five Fields

A standard cron expression has five fields separated by spaces. Each field represents a time unit, read left to right from smallest to largest:

┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-7, where 0 and 7 = Sunday)
│ │ │ │ │
* * * * *

The asterisk (*) means "every value." So * * * * * runs every minute of every hour of every day. Most of the cron expressions you'll write replace one or more of those asterisks with specific values or patterns.

Special Characters

Four special characters let you build schedules beyond simple fixed times:

CharacterMeaningExampleResult
*Every value* * * * *Every minute
,List of values0 8,12,18 * * *At 8 AM, 12 PM, and 6 PM
-Range of values0 9-17 * * *Every hour from 9 AM to 5 PM
/Step interval*/15 * * * *Every 15 minutes

These characters combine freely. 0 9-17/2 * * 1-5 means "at minute 0, every 2 hours from 9 AM through 5 PM, Monday through Friday." That's a business-hours-only schedule with a single expression.

20 Cron Expression Examples You'll Actually Use

These cover the schedules that show up repeatedly in real infrastructure. Copy the expression, verify it with the PinusX Cron Parser, and drop it into your crontab.

ScheduleExpressionNotes
Every minute* * * * *Health checks, queue polling
Every 5 minutes*/5 * * * *Monitoring, cache refresh
Every 15 minutes*/15 * * * *API syncs, report generation
Every 30 minutes*/30 * * * *Data aggregation
Every hour (on the hour)0 * * * *Hourly log rotation
Every 6 hours0 */6 * * *DNS refresh, cert checks
Daily at midnight0 0 * * *Backups, daily reports
Daily at 3 AM0 3 * * *Off-peak maintenance
Twice daily (9 AM and 6 PM)0 9,18 * * *Business-hours notifications
Every weekday at 8 AM0 8 * * 1-5Morning deployment checks
Every Monday at 9 AM0 9 * * 1Weekly status reports
Every Friday at 5 PM0 17 * * 5End-of-week summaries
Weekends only at noon0 12 * * 0,6Weekend maintenance windows
1st of every month at midnight0 0 1 * *Monthly billing, reports
Every quarter (Jan, Apr, Jul, Oct 1st)0 0 1 1,4,7,10 *Quarterly cleanup
Every 10 min during business hours*/10 9-17 * * 1-5Business-hours monitoring
First Monday of each month at 6 AM0 6 1-7 * 1Runs when the 1st-7th is a Monday
Last day of month (28th, approx)0 0 28 * *Cron has no "last day" — use 28th as safe default
Every January 1st at midnight0 0 1 1 *Annual tasks, license renewal
Every Sunday at 2 AM0 2 * * 0Weekly database vacuum

Cron Gotchas That Catch Everyone

Timezone Confusion

Cron jobs run in the system's timezone by default — not UTC, not your local timezone, but whatever timedatectl reports on the server. If your server is set to UTC but you're thinking in US Eastern time, your "midnight backup" runs at 7 PM or 8 PM Eastern depending on daylight saving time. Always check the server timezone with date or timedatectl before writing cron schedules. Better yet, set all servers to UTC and do the timezone math explicitly.

Day-of-Week Numbering

Sunday is both 0 and 7 in most cron implementations, but not all. Some systems use 1 for Monday through 7 for Sunday. Others start with 0 for Sunday. The POSIX standard says 0 = Sunday, and that's what Linux cron uses. But if you're using a cron library in Node.js or Python, check the documentation — node-cron and cron npm packages differ on this. Use named days (SUN, MON) when your cron implementation supports them to avoid ambiguity.

Day-of-Month vs Day-of-Week: The OR Trap

When you set both the day-of-month and day-of-week fields, cron treats them as an OR condition, not AND. The expression 0 0 15 * 5 doesn't mean "midnight on the 15th if it's a Friday." It means "midnight on the 15th of every month, AND midnight every Friday." That's more executions than you expected. If you need both conditions, you'll need to handle the logic in your script itself.

Overlapping Executions

If your cron job takes 10 minutes to complete but runs every 5 minutes, you'll have overlapping instances fighting over the same resources — writing to the same files, hitting the same API rate limits, or corrupting shared data. Cron doesn't care whether the previous run finished. It fires on schedule regardless.

The standard fix is a lockfile:

#!/bin/bash
LOCKFILE="/tmp/my-job.lock"

if [ -f "$LOCKFILE" ]; then
  echo "Previous run still active, skipping"
  exit 0
fi

trap "rm -f $LOCKFILE" EXIT
touch "$LOCKFILE"

# Your actual job here
/usr/local/bin/sync-data.sh

Or use flock, which handles edge cases like stale lockfiles from crashed processes:

# In crontab:
*/5 * * * * flock -n /tmp/my-job.lock /usr/local/bin/sync-data.sh

No "Last Day of Month" Syntax

Standard cron has no way to express "the last day of the month." Since months have 28, 29, 30, or 31 days, you can't use a fixed number. The common workaround is to run a daily job that checks whether tomorrow is the 1st:

# Run at 11:55 PM daily, but only execute if tomorrow is the 1st
55 23 * * * [ "$(date -d tomorrow +%d)" = "01" ] && /path/to/monthly-job.sh

Crontab Quick Reference

Managing cron jobs on a Linux system uses the crontab command:

# Edit your user's crontab
crontab -e

# List current cron jobs
crontab -l

# Remove all cron jobs (careful!)
crontab -r

# Edit another user's crontab (requires root)
sudo crontab -u www-data -e

Each line in a crontab file follows the format: expression command. Lines starting with # are comments. You can set environment variables at the top of the file — MAILTO="" suppresses the email output that cron sends by default when a job produces output.

Test Before You Deploy

The single most useful habit for working with cron expressions is to verify them before they hit production. The PinusX Cron Expression Parser takes any cron expression and shows you the next 10 execution times in plain English. Paste in 0 9-17/2 * * 1-5 and see exactly when it fires — no mental arithmetic required, no waiting until the next scheduled run to confirm it worked.

For related DevOps tasks, the PinusX Chmod Calculator helps when you're setting permissions on the scripts your cron jobs execute (a 644 script won't run — you need 755 or at least u+x). And when you're debugging JSON config files that your cron jobs consume, the PinusX JSON Formatter processes everything client-side so your production configs stay off third-party servers.

Monitor Your APIs & Services

Get instant alerts when your endpoints go down. 60-second checks, free forever.

Start Monitoring Free →