On this page
cron syntax
The POSIX standard syntax for scheduling recurring background jobs, specifying the exact minute, hour, day, and month a script should execute.
What it is
Computers are excellent at doing things predictably. cron is a time-based job scheduler built into Unix-like operating systems. It allows administrators to automatically run scripts, execute database backups, or send daily report emails without human intervention.
While modern orchestrators like Kubernetes offer CronJob resources and cloud providers offer services like AWS EventBridge, they all rely almost exclusively on the original POSIX cron syntax to define the schedule. This syntax is a compact string of five fields separated by spaces, representing the exact temporal coordinates for execution.
Why it matters
If you write a script to clear temporary logs from a server, and you schedule it to run “every night,” you must translate “every night” into machine language.
The cron syntax is the universal language for recurring time in computing. Whether you are configuring a legacy Linux server, defining a GitHub Actions workflow, or scheduling a Kubernetes Pod, you must express your schedule using this exact string format. Failing to understand the syntax can result in jobs running thousands of times a minute (destroying the server) or never running at all (resulting in overflowing disks and data loss).
How to implement
A cron expression consists of five space-separated fields, followed by the command to execute.
* * * * * command_to_execute
- - - - -
| | | | |
| | | | +----- Day of the week (0 - 7) (Sunday is both 0 and 7)
| | | +------- Month (1 - 12)
| | +--------- Day of the month (1 - 31)
| +----------- Hour (0 - 23)
+------------- Minute (0 - 59)
The Characters
*(Asterisk): “Every”. If the minute field is*, it means every minute.,(Comma): “Value list”.1,15,30in the minute field means run at minutes 1, 15, and 30.-(Hyphen): “Range”.9-17in the hour field means run every hour from 9 AM to 5 PM./(Slash): “Step values”.*/15in the minute field means run every 15 minutes.
Common Examples
Run exactly at midnight every day:
0 0 * * * /path/to/backup.sh
Run at 2:30 AM every Sunday:
30 2 * * 0 /path/to/cleanup.sh
Run every 5 minutes during standard business hours (9 AM to 5 PM), Monday through Friday:
*/5 9-17 * * 1-5 /path/to/healthcheck.sh
Common mistakes
The * * * * * Trap
Developers often misunderstand the difference between 0 (the zero-th minute) and * (every minute). If a developer wants a job to run once an hour, they might mistakenly write * 1 * * * thinking it means “once at 1 AM.” What this actually means is “run every single minute, but only during the 1 AM hour.” The job will trigger 60 times in a row, likely causing massive database contention. The correct expression is 0 1 * * *.
Assuming Local Timezones
When defining a CronJob in Kubernetes or a workflow in GitHub Actions, the scheduling engine almost always runs in UTC (Coordinated Universal Time). If an engineer in New York (EST, UTC-5) schedules a job for 0 9 * * * expecting it to run at 9:00 AM when they get to the office, the job will actually execute at 4:00 AM local time. Schedules must always be mathematically converted to UTC unless the orchestrator explicitly supports a timezone configuration flag.
The Day-of-Month / Day-of-Week OR Logic
The day-of-month (field 3) and day-of-week (field 5) fields interact in a uniquely confusing way. If both are specified, the cron daemon treats them as an OR condition, not an AND condition.
For example, 0 0 1,15 * 5 does not mean “Run on the 1st and 15th, but only if they fall on a Friday.” It means “Run on the 1st, the 15th, AND every Friday.”
Verification
Because a single misplaced asterisk can trigger a script thousands of times, you must verify complex cron expressions before committing them to infrastructure.
Use a linter or an open-source parsing tool like crontab.guru to translate the string back into human-readable text.
# Many Linux distributions include a command-line parser
# Alternatively, write a dry-run log to verify execution:
echo "*/15 * * * * echo 'Cron executed' >> /tmp/cron.log" | crontab -Related topics
Sources & further reading
- POSIX.1-2017: crontab specification - The Open Group