How Cron Jobs Work: A Complete Developer Guide

BY TOOLS.FUN  ·  MARCH 28, 2026  ·  6 min read

Cron is one of the oldest and most reliable tools in the Unix toolkit — a time-based job scheduler that has been running background tasks on servers since 1975. Despite its age, the cron expression format is still used in modern platforms like Kubernetes CronJobs, GitHub Actions, AWS EventBridge, and Google Cloud Scheduler. Understanding how cron works makes you more effective with all of them.

Related tools: use our Timestamp Converter to verify cron execution times, RegExp Tester to parse cron log output, and Diff Tool to compare crontab versions before and after edits.

What is Cron?

Cron is a daemon (a background process) that runs continuously on Unix-like systems. It reads a configuration file called a crontab (cron table) and executes shell commands at specified times. It's the canonical solution for recurring tasks: database backups, report generation, cache warming, log rotation, and cleanup jobs.

The crontab file contains one job per line. Each line has a time/date specification followed by the command to run. The daemon wakes up every minute, checks all crontabs, and runs any job whose schedule matches the current time.

The Cron Expression Format

A standard cron expression has five fields separated by spaces, followed by the command:

┌───────────── minute        (0–59)
│ ┌─────────── hour          (0–23)
│ │ ┌───────── day of month  (1–31)
│ │ │ ┌─────── month         (1–12)
│ │ │ │ ┌───── day of week   (0–7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * * command to execute

An asterisk * means "every valid value for this field". So * * * * * runs the command every minute of every hour of every day.

Key point: Some platforms (like AWS EventBridge and many cloud schedulers) use a 6-field format that adds a year field at the end, or reorders the seconds field. Always check the platform's documentation.

Special Characters Explained

Five special characters control the scheduling logic:

0 9 * * 1-5       # 9:00 AM every weekday (Mon–Fri)
*/15 * * * *      # every 15 minutes
0 0 1,15 * *      # midnight on the 1st and 15th of each month
0 2 * * 0         # 2:00 AM every Sunday

Common Cron Schedules

Many cron implementations support shorthand strings for common schedules:

@yearly   (or @annually)  →  0 0 1 1 *
@monthly                  →  0 0 1 * *
@weekly                   →  0 0 * * 0
@daily    (or @midnight)  →  0 0 * * *
@hourly                   →  0 * * * *
@reboot                   →  runs once at startup
Key point: @reboot runs the command once when the cron daemon starts, not at each system boot — though in practice the daemon starts at boot. It's useful for initialisation tasks but not a substitute for proper init systems like systemd.

Managing Crontabs

Each user on a Unix system has their own crontab. Use crontab -e to edit your crontab in the default editor, crontab -l to list it, and crontab -r to remove it (careful — there's no confirmation prompt). System-wide crontabs live in /etc/cron.d/, /etc/cron.daily/, /etc/cron.weekly/, and /etc/cron.monthly/.

Always redirect output when running cron jobs, or cron will try to email the output to the user (which often silently fails on servers without mail configured):

0 3 * * * /usr/bin/backup.sh >> /var/log/backup.log 2>&1

Cron in Modern Infrastructure

Kubernetes CronJob — uses the same 5-field format to schedule pods. The spec.schedule field accepts standard cron expressions. Kubernetes handles retries, concurrency policies, and history limits.

GitHub Actions — the schedule trigger uses cron syntax to run workflows on a schedule. Note that GitHub Actions runs in UTC and may have a few minutes of delay under heavy load.

AWS EventBridge — supports both cron expressions (6-field, with year) and rate expressions (rate(5 minutes)).

Key point: Cron-based schedulers in distributed systems don't guarantee exactly-once execution. If your job is not idempotent, add a distributed lock or use a proper job queue.

Timezone Gotchas

The system cron daemon runs in the system timezone, which on servers is almost always UTC. A job scheduled for 0 9 * * * runs at 09:00 UTC — which may be 4:00 AM or 10:00 AM in your local timezone depending on DST. Always document the timezone assumption explicitly, and consider using a scheduler that has explicit timezone support (like Kubernetes CronJob with the timeZone field, added in Kubernetes 1.25).

Daylight Saving Time transitions can cause jobs to run twice or be skipped. A job scheduled for 0 2 * * * may be skipped on the night clocks spring forward, or run twice when they fall back.

Test Your Cron Expression

The Cron Expression Tester at Tools.Fun shows you the next 10 scheduled run times for any cron expression, so you can verify your schedule before deploying it. It also translates cryptic expressions into plain English — paste 0 */4 * * 1-5 and see "every 4 hours on weekdays".

← Back