Cron is the scheduler built into Linux and macOS, and its five-field expressions are now used everywhere: crontab, Kubernetes CronJobs, GitHub Actions, cloud schedulers and many frameworks. Once you know the five fields and four symbols, you can read and write any schedule.
The five fields
┌───────── minute (0–59) │ ┌─────── hour (0–23) │ │ ┌───── day of month (1–31) │ │ │ ┌─── month (1–12 or JAN–DEC) │ │ │ │ ┌─ day of week (0–7, 0 and 7 are Sunday, or SUN–SAT) │ │ │ │ │ * * * * *
So 30 9 * * 1-5 means minute 30, hour 9, any day of the month, any month, Monday to Friday: 9:30 every weekday.
The four symbols
| Symbol | Meaning | Example |
|---|---|---|
* | Every value | * * * * * runs every minute |
, | A list | 0 9,18 * * * runs at 9:00 and 18:00 |
- | A range | 0 9 * * 1-5 runs Monday to Friday |
/ | A step | */15 * * * * runs every 15 minutes |
Shortcuts such as @hourly, @daily, @weekly, @monthly and @yearly also work in most cron implementations.
20 ready-to-use examples
| Expression | Runs |
|---|---|
* * * * * | Every minute |
*/5 * * * * | Every 5 minutes |
*/15 * * * * | Every 15 minutes |
0 * * * * | Every hour, on the hour |
30 * * * * | At 30 minutes past every hour |
0 */2 * * * | Every 2 hours |
0 9-18 * * 1-5 | Every hour from 9:00 to 18:00, Monday to Friday |
0 0 * * * | Every day at midnight |
0 9 * * * | Every day at 9:00 |
30 2 * * * | Every day at 2:30 (a quiet time for backups) |
0 9 * * 1-5 | Weekdays at 9:00 |
0 10 * * 6,0 | Saturdays and Sundays at 10:00 |
0 9 * * 1 | Every Monday at 9:00 |
0 0 1 * * | The 1st of every month at midnight |
0 9 1,15 * * | The 1st and 15th of every month at 9:00 |
0 18 * * 5 | Every Friday at 18:00 |
0 0 1 1 * | Every year on 1 January |
0 0 1 */3 * | At midnight on the 1st of every third month (quarterly) |
*/10 9-17 * * 1-5 | Every 10 minutes during office hours on weekdays |
0 3 * * 0 | Every Sunday at 3:00 |
Time zones
A cron expression has no time zone of its own; it runs in the time zone of whatever runs it:
- Linux crontab uses the server’s time zone, which is often UTC on cloud servers.
- GitHub Actions schedules always use UTC. To run at 9:00 in India (UTC+5:30), use
30 3 * * *. - Kubernetes CronJobs use the controller’s time zone unless you set
spec.timeZone(for exampleAsia/Kolkata).
Check the next run times in the right zone with the Cron Explainer, or build a schedule visually with the Cron Generator.
Pitfalls to avoid
Day of month and day of week together
When both are set, standard cron runs when either matches. 0 0 13 * 5 runs on the 13th of every month and every Friday, not only on Friday the 13th.
Steps reset every period
0 0 */10 * * runs on the 1st, 11th, 21st and 31st, then starts again on the 1st. Steps do not carry over between months, so “every 10 days” is not exact across month ends.
The % sign in crontab
In a crontab line, % in the command means a new line. Escape it as \%, for example in date +\%F.
Overlapping runs
If a job can take longer than its interval, two copies may run at once. Use a lock (such as flock on Linux) or concurrencyPolicy: Forbid in Kubernetes.
>> /var/log/myjob.log 2>&1 to the end of a crontab command so you can see what happened.Seconds, Quartz and Spring
Some schedulers, including Quartz and Spring’s @Scheduled, add a seconds field at the front (six fields) and Quartz can add a year at the end. Quartz numbers days of the week 1–7 from Sunday and uses ? for “no specific value” and special characters like L (last) and # (nth weekday). The Cron Explainer understands these too.