The automation of repetitive tasks is a cornerstone of Unix-like operating systems, and for decades, the cron daemon has been the undisputed king of time-based task scheduling. Whether you are rotating logs on a server, triggering database backups, or simply reminding yourself to step away from the keyboard, mastering cron syntax is essential for any systems engineer or power user.
The Origins of Cron: A Brief History
The cron utility is nearly as old as the Unix operating system itself. In the early 1970s, as Unix was being developed at Bell Labs by pioneers like Ken Thompson and Dennis Ritchie, the need arose for a program that could execute tasks in the background on a predefined schedule.
Ken Thompson authored the original implementation of cron. It was designed with the extreme hardware limitations of the era in mind—built to be highly efficient, running as a background daemon (crond) that wakes up exactly once a minute, checks the schedule table, executes any due commands, and immediately goes back to sleep.
In the late 1980s, Paul Vixie wrote "Vixie cron," a complete rewrite that introduced numerous enhancements, including user-specific crontab files and expanded syntax (like @reboot and @daily). Vixie cron was widely adopted and remains the underlying engine for the cron implementations found in many modern Linux distributions today.
Some Interesting Facts
The name "cron" is derived from Chronos, the Greek personification of time.
The
tabincrontabstands for "table," making it literally a time table.The daemon checks the system time every single minute without fail. If the system is powered down when a job is scheduled, standard
cronmisses the job entirely (which is whyanacronwas later invented for laptops and desktops).
Cronjob Cheatsheet
Every user on a Linux system can maintain their own scheduling table. You interact with it using the crontab command:
crontab -e: Edit your current crontab file.crontab -l: List your current cron jobs.crontab -r: Remove your crontab file (use with caution).
A standard cron expression consists of five time-and-date fields, followed by the command to be executed.
The Five Fields
| Field | Range | Description |
|---|---|---|
| Minute | 0-59 | Exact minute the job runs |
| Hour | 0-23 | Hour of the day (24-hour clock) |
| Day of Month | 1-31 | Day of the month |
| Month | 1-12 | Month of the year |
| Day of Week | 0-7 | 0 and 7 usually represent Sunday |
Special Characters
| Symbol | Meaning | Example |
|---|---|---|
* |
Any/Every |
* in the hour field means "every hour" |
, |
Value list separator |
1,15 in DOM means "1st and 15th" |
- |
Range of values |
9-17 in Hour means "9 AM to 5 PM" |
/ |
Step values |
*/10 in Minute means "every 10 minutes" |
Experiment with different schedules using this interactive cron expression builder to see how the syntax translates into plain English before adding it to your server.
Key insight: The cron daemon runs in a restricted environment. By default, it has a very minimal
PATH(often just/usr/bin:/bin). If your script uses custom binaries, always provide absolute paths.
Project: Building a Drink Water Reminder
Let's put this into practice by building a hydration reminder that runs every 30 minute.
To set a reminder for every "x" minutes, use the */x syntax in the minute field.
For example, to run your reminder every 30 minutes, your cron expression would look like this: */30 * * * *
Option 1: Desktop GUI Notification
If you are using a Linux desktop environment (like GNOME, KDE, or XFCE), you can trigger native desktop notifications using notify-send.
Because cron runs in the background detached from your graphical session, it doesn't know where to send the notification display. We have to export the DISPLAY and DBUS_SESSION_BUS_ADDRESS variables (the exact variables vary slightly by Linux distribution, but DBUS_SESSION_BUS_ADDRESS is the most critical for modern systems).
Open your crontab (crontab -e) and add this line:
Bash
*/30 * * * * DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus" notify-send "Hydration Check" "Time to drink a glass of water!" -u critical
The -u critical flag ensures the notification stays on screen until you manually dismiss it.
Option 2: Terminal Broadcast (No GUI required)
If you live in the terminal or are working on a headless server (like a Raspberry Pi or a VPS), a GUI notification won't work. Instead, we can use the wall command, which broadcasts a message to the terminals of all currently logged-in users.
Open your crontab and add this line:
Bash
*/30 * * * * echo "Time to drink a glass of water!" | wall
Alternatively, if you only want to send the reminder to a specific active terminal session (e.g., /dev/pts/0), you can redirect standard output directly to that pseudo-terminal:
Bash
*/30 * * * * echo -e "\n\aHydration Check: Drink some water!\n" > /dev/pts/0
(The \a triggers the terminal bell sound, if enabled).
Challenge: Test Your Cron Knowledge!
Comment below with just the cron time expression (the 5 fields) for each of these scenarios:
Run at 3:15 AM every Sunday.
Execute every 15 minutes, every day.
Exactly at midnight on the 1st day of every month.
Run at 6:30 PM, but only on weekdays (Monday through Friday).
Trigger every 5 minutes during standard office hours (9 AM to 5 PM), Monday through Friday.

Top comments (0)