Cron Jobs Explained: Syntax, Examples and Common Pitfalls

Master the five-field cron syntax with real examples for Linux crontab, Kubernetes CronJobs and GitHub Actions, and learn how to debug jobs that never run.

Last updated · 2026-09-08

The five fields

A cron expression has five space-separated fields: minute (0–59), hour (0–23), day of month (1–31), month (1–12) and day of week (0–6, Sunday = 0). An asterisk means 'every'. So '30 2 * * *' runs at 02:30 every day. Paste any expression into our cron explainer to read it in plain English.

Operators

Lists: '0 8,12,18 * * *' runs three times a day. Ranges: '0 9 * * 1-5' runs on weekdays. Steps: '*/10 * * * *' every ten minutes; '0 */6 * * *' every six hours.

Real-world examples

Nightly database backup at 03:00: '0 3 * * *'. Weekly report every Monday at 08:00: '0 8 * * 1'. Monthly invoice on the 1st at midnight: '0 0 1 * *'. Cache warm-up every 15 minutes during office hours: '*/15 9-17 * * 1-5'.

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

Why your cron job doesn't run

Environment: cron runs with a minimal PATH and no shell profile. Use absolute paths for commands and files.

Permissions: the script must be executable (chmod +x) — our chmod calculator helps with the numbers.

Time zone: cron uses the server's zone. GitHub Actions and Kubernetes default to UTC.

Silent failures: without output redirection, errors disappear. Always log stdout and stderr.

Percent signs: % has a special meaning in crontab and must be escaped as \%.

Cron in Kubernetes and GitHub Actions

Kubernetes CronJobs use the same syntax in spec.schedule and support a timeZone field. Set concurrencyPolicy: Forbid to avoid overlapping runs. GitHub Actions uses on.schedule with cron strings in UTC; note that scheduled workflows may be delayed during busy periods and are disabled after 60 days of repository inactivity.

Alternatives worth knowing

On modern Linux, systemd timers offer logging via journalctl, dependency handling and catch-up of missed runs with Persistent=true. Our systemd service generator creates the unit files for you.

Try the tools from this article

← All tutorials