How does crontab syntax work?
Reviewed by Prabath Thalangama · Last updated
A crontab line has five time fields (minute, hour, day of month, month and day of week) followed by the command to run. Each field takes a value, a list (1,15), a range (1-5), a step (*/10) or * for every value. This generator builds the expression, describes it in plain English and previews the next five run times.
The next run times are shown in your browser's time zone. Cron itself uses the server's time zone, so check what timedatectl says on the server if the two differ.
The same five-field syntax is used by Kubernetes CronJobs, GitHub Actions schedules (always UTC) and most CI systems, so the generator is useful well beyond crontab -e.
How do I create a cron schedule?
- Start from a preset or set each of the five fields.
- Check the plain-English description and the next five run times.
- Copy the expression into crontab -e, a file in /etc/cron.d (which adds a user field), or a CronJob's spec.schedule.
How to read the results
- Expression
- The five-field schedule, for example 30 2 * * 1-5.
- In plain English
- What the expression means, such as 'At 02:30 on every day-of-week from Monday through Friday'.
- Next 5 run times
- When the job would run next, so you can confirm the schedule before relying on it.
Why isn't my cron job running?
The command works in a shell but not in cron
Cron runs jobs with a minimal environment: a short PATH, no profile, and /bin/sh. Use absolute paths to commands and files, or set PATH at the top of the crontab.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
30 2 * * * /usr/local/bin/backup.sh% characters in the command
In a crontab line, an unescaped % is turned into a newline. Escape it as \% (common with date +%F).
0 1 * * * tar czf /backup/etc-$(date +\%F).tar.gz /etcDay of month and day of week together
When both fields are restricted, cron runs the job when either matches, not when both do. 0 9 1 * 1 runs on the 1st of the month and on every Monday.
No output and no idea whether it ran
Redirect output to a log file, and check the cron log or journal.
*/15 * * * * /opt/app/sync.sh >> /var/log/app-sync.log 2>&1
# Did it run?
journalctl -u cron --since today # Debian/Ubuntu
journalctl -u crond --since today # RHEL/Rocky/AlmaExamples and command-line equivalents
Common schedules
*/5 * * * * every 5 minutes
0 * * * * every hour, on the hour
0 0 * * * every day at midnight
30 2 * * 1-5 02:30 on weekdays
0 9 * * 1 09:00 every Monday
0 0 1 * * midnight on the 1st of each month
@reboot once at startup (Vixie cron and cronie)Manage your crontab
crontab -e # edit
crontab -l # list
sudo crontab -u www-data -l # another user'sThe same schedule as a Kubernetes CronJob
spec.timeZone is stable since Kubernetes 1.27; without it the controller's time zone (usually UTC) is used.
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-backup
spec:
schedule: "30 2 * * 1-5"
timeZone: "Asia/Colombo"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: busybox:1.36
command: ["sh", "-c", "echo backup"]Frequently asked questions
What does */5 * * * * mean?
Run every 5 minutes. */n in a field means every n units, starting from the field's lowest value.
Which time zone does cron use?
The system time zone of the server, unless your cron implementation supports CRON_TZ or TZ variables. GitHub Actions schedules always use UTC, and Kubernetes CronJobs use spec.timeZone if set.
Cron or systemd timers?
Both work. systemd timers add logging in the journal, dependency handling, randomized delays and catch-up of missed runs (Persistent=true). Cron is simpler and available everywhere.
Can cron run a job every 30 seconds?
No, a minute is the smallest unit. Run a script every minute that does its work twice with a sleep 30 between, or use a systemd timer with OnUnitActiveSec=30s.