Home / Blog / Cron Jobs Explained: The Complete Beginner's Tutorial

Cron Jobs Explained: The Complete Beginner's Tutorial

9 min read · Updated 2026-08-07

Every server you've ever touched probably has cron jobs running right now — log rotations, backups, health checks. The syntax is five fields and 40 years old, and once it clicks, it clicks forever.

The five fields

A cron expression is: minute hour day-of-month month day-of-week command

┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6, Sun=0)
│ │ │ │ │
* * * * *

* means "every value"; */5 means "every 5 units"; 1,15 means "the 1st and 15th"; 9-17 means "9am through 5pm".

The recipes everyone actually uses

  • 0 * * * * — top of every hour (hourly cleanup jobs)
  • 0 0 * * * — midnight daily (nightly backups)
  • 0 9 * * 1-5 — 9am on weekdays (standup reminders)
  • */15 * * * * — every 15 minutes (health checks)
  • 0 0 1 * * — first of the month (monthly reports)
  • 30 2 * * 0 — 2:30am Sundays (weekend maintenance)

Don't memorize — build them visually with the cron expression builder and copy the result.

The gotchas that bite everyone

1. Day-of-month AND day-of-week is an OR. 0 0 13 * 5 runs on the 13th and every Friday — not "Friday the 13th". 2. Timezone: cron uses the server's local time unless CRON_TZ is set — a daylight-saving shift can fire a job twice or never. 3. Minimal environment: cron runs with a tiny PATH, so always use absolute paths for binaries (/usr/bin/python3, not python3). 4. The % character needs escaping as \% in crontab lines.

Testing before you deploy

Never learn about a bad schedule from a 3am page. Validate the expression and preview the next five fire times in the builder, then confirm on staging: temporarily set the job to * * * * * (every minute), watch the logs for two minutes, then switch to the real schedule.

Modern alternatives

systemd timers (better logging), Kubernetes CronJobs (cluster-aware), and GitHub Actions schedules all use the same five-field syntax — learning cron once pays off across every platform.

Sponsor — keeps these guides free

Frequently Asked Questions

What does */5 mean in cron?

Every 5 units of that field. In the minute field, */5 = at :00, :05, :10 … :55 every hour.

How do I run a cron job on the last day of the month?

Cron can't express it directly. The standard trick: run daily and exit unless tomorrow's date is the 1st — [ $(date -d tomorrow +%d) -eq 1 ] || exit 0.

Why isn't my cron job running?

Check three things: absolute paths for all commands, the daemon is running (systemctl status cron), and stderr isn't being discarded — redirect to a log: * * * * * /path/cmd >> /var/log/myjob.log 2>&1.

How do I see my scheduled crons?

crontab -l lists your user crontab; system-wide ones live in /etc/crontab and /etc/cron.d/.

💜 Found this guide useful?

☕ Buy Me a Coffee