A quick reference of cron schedules you can paste into crontab -e. Each line has five time fields followed by the command:

minute  hour  day-of-month  month  day-of-week  command
0-59    0-23  1-31          1-12   0-7 (0/7=Sun)

For how cron works — editing, environment, logging — see the crontab guide.

Special characters

Symbol Meaning Example
* Every value * in hour = every hour
, List 1,15 = 1st and 15th
- Range 1-5 = Monday to Friday
/ Step */10 = every 10
@… Shortcut @daily, @reboot

Minutes and hours

* * * * *        # every minute
*/2 * * * *      # every 2 minutes
*/5 * * * *      # every 5 minutes
*/10 * * * *     # every 10 minutes
*/15 * * * *     # every 15 minutes
*/30 * * * *     # every 30 minutes
0,30 * * * *     # on the hour and half past (same as above, explicit)
5-59/15 * * * *  # at :05, :20, :35, :50
0 * * * *        # every hour, on the hour
15 * * * *       # every hour at :15
0 */2 * * *      # every 2 hours
0 */6 * * *      # every 6 hours (00, 06, 12, 18)
0 9-17 * * *     # every hour from 09:00 to 17:00
*/10 9-17 * * 1-5   # every 10 minutes during office hours, weekdays

Note that */7 resets every hour: minutes 0, 7, 14 … 56, then 0 again — so the gap from :56 to :00 is only 4 minutes. Steps that don’t divide 60 (or 24) evenly aren’t truly regular.

Daily

0 0 * * *        # midnight
30 2 * * *       # 02:30
0 6,18 * * *     # 06:00 and 18:00
45 23 * * *      # 23:45
@daily           # same as 0 0 * * *

Avoid scheduling everything at exactly midnight: logrotate, package updates and other jobs often run then. Pick odd minutes like 17 3 * * *.

Weekly

0 0 * * 0        # Sunday at midnight
0 8 * * 1        # Monday at 08:00
0 9 * * 1-5      # weekdays at 09:00
0 10 * * 6,0     # weekends at 10:00
0 17 * * 5       # Friday at 17:00
@weekly          # Sunday at midnight

Day names work in most cron implementations: 0 8 * * mon, 0 9 * * mon-fri.

Monthly and yearly

0 0 1 * *        # first day of the month at midnight
0 3 15 * *       # the 15th at 03:00
0 0 1,15 * *     # 1st and 15th
0 0 1 */3 *      # first day of every quarter (Jan, Apr, Jul, Oct)
0 0 1 1 *        # 1 January
@monthly         # 0 0 1 * *
@yearly          # 0 0 1 1 *

Tricky schedules

Last day of the month — cron has no “last day” field. Run on days 28–31 and test whether tomorrow is the 1st:

0 23 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /usr/local/bin/month-end.sh

First Monday of the month — day-of-month and day-of-week combine with OR, so 0 9 1-7 * 1 runs on days 1–7 and every Monday. Test the weekday in the command instead:

0 9 1-7 * * [ "$(date +\%u)" = "1" ] && /usr/local/bin/report.sh

Every 90 seconds / sub-minute — cron’s resolution is one minute. Run two staggered entries, or use a loop or a systemd timer:

* * * * * /usr/local/bin/task.sh
* * * * * sleep 30; /usr/local/bin/task.sh     # every 30 seconds

Every other week — not expressible directly. Run weekly and check the ISO week number:

0 9 * * 1 [ $(( $(date +\%V) \% 2 )) -eq 0 ] && /usr/local/bin/biweekly.sh

Remember to escape % as \% inside crontab lines.

Startup and random delays

@reboot /usr/local/bin/on-boot.sh
@reboot sleep 60 && /usr/local/bin/after-network.sh

To spread load (for example, many servers hitting the same API), add a random delay:

0 3 * * * sleep $((RANDOM \% 1800)); /usr/local/bin/sync.sh

$RANDOM needs bash — set SHELL=/bin/bash at the top of the crontab.

Common real-world jobs

# Nightly database backup
30 2 * * * /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1

# Renew certificates (Certbot already ships a timer — only if you don't use it)
17 4 * * * certbot renew --quiet

# Laravel scheduler
* * * * * cd /var/www/app && php artisan schedule:run >> /dev/null 2>&1

# WordPress cron (with DISABLE_WP_CRON in wp-config.php)
*/5 * * * * cd /var/www/site && wp cron event run --due-now --quiet

# Clean temp files older than 7 days
0 4 * * * find /var/www/app/tmp -type f -mtime +7 -delete

# Prune unused Docker images weekly
0 5 * * 0 docker image prune -af --filter "until=168h"

See WordPress real cron and mysqldump backups for the full setups.

Validate before you trust

A wrong field silently runs a job at the wrong time. Paste expressions into an online cron explainer, or check what will happen by watching the log after the first expected run:

grep CRON /var/log/syslog | tail

Cron vs other schedulers

The five-field format is shared by many tools — Kubernetes CronJobs, GitHub Actions schedule, CI systems — but some (Quartz, AWS EventBridge) add a seconds or year field and differ on day-of-week numbering. Check which flavour you’re writing for.

Need a machine that’s always on to run these schedules? Any Linux VPS does the job, and the smallest plans are plenty for scheduled tasks.

  • Cron
  • Linux
  • Automation