How to Use Cron Expressions: A Complete Guide
Cron is the time-based job scheduler found in Unix-like operating systems. Whether you're scheduling database backups, sending automated emails, cleaning up log files, or running periodic scripts, cron expressions are the standard way to define when jobs should run. Despite their compact syntax, cron expressions can seem cryptic at first. This guide will make them second nature.
What Is Cron?
Cron (from the Greek word "chronos" meaning time) is a daemon that runs in the background on Unix/Linux systems. It reads a configuration file called the crontab (cron table) which lists commands to be executed at specified times. Cron is also used in many modern platforms: GitHub Actions, AWS CloudWatch, Kubernetes CronJobs, CI/CD pipelines, and cloud functions.
Cron Expression Syntax
A standard cron expression has five fields separated by spaces:
┌───────────── minute (0–59) │ ┌───────────── hour (0–23) │ │ ┌───────────── day of month (1–31) │ │ │ ┌───────────── month (1–12) │ │ │ │ ┌───────────── day of week (0–7, where 0 and 7 = Sunday) │ │ │ │ │ * * * * *
Field Details
- Minute: 0–59. The minute within the hour when the job runs
- Hour: 0–23. Uses 24-hour format (0 = midnight, 13 = 1 PM)
- Day of Month: 1–31. The calendar day
- Month: 1–12 (or JAN–DEC)
- Day of Week: 0–7 (or SUN–SAT). Both 0 and 7 represent Sunday
Special Characters
Asterisk (*)
Matches every value for that field. * * * * * runs every minute of every hour of every day.
Comma (,)
Specifies a list of values. 0 8,12,18 * * * runs at 8:00, 12:00, and 18:00.
Hyphen (-)
Specifies a range. 0 9-17 * * * runs every hour from 9:00 to 17:00 (business hours).
Slash (/)
Specifies step values. */15 * * * * runs every 15 minutes (at :00, :15, :30, :45). 0 */2 * * * runs every 2 hours.
Question Mark (?)
Used in some cron implementations (like Quartz) to mean "no specific value" for day-of-month or day-of-week fields when the other is specified.
Hash (#)
In some implementations, specifies the nth occurrence of a weekday in a month. 0 0 * * 5#2 means the second Friday of every month.
Common Cron Patterns
Here are the most frequently used cron schedules:
Every Minute
* * * * *
Runs every single minute. Used for monitoring or real-time processing.
Every Hour
0 * * * *
Runs at the start of every hour (00 minutes).
Every Day at Midnight
0 0 * * *
Classic daily job — runs at 00:00 every day. Common for backups, reports, and cleanup.
Every Day at 9 AM
0 9 * * *
Great for morning notification emails or daily report generation.
Every Monday at 8 AM
0 8 * * 1
Weekly jobs — Monday morning reports, weekly digests, etc.
Every Weekday at 6 PM
0 18 * * 1-5
Runs Monday through Friday at 18:00. Perfect for end-of-day summaries.
First Day of Every Month
0 0 1 * *
Monthly tasks — invoicing, monthly reports, subscription renewals.
Every 15 Minutes During Business Hours
*/15 9-17 * * 1-5
Runs at :00, :15, :30, :45 during 9 AM–5 PM, Monday through Friday.
Twice a Day (9 AM and 6 PM)
0 9,18 * * *
Useful for morning and evening checks or notifications.
Every Quarter (Jan, Apr, Jul, Oct 1st)
0 0 1 1,4,7,10 *
Quarterly reports and financial calculations.
Cron in Modern Platforms
GitHub Actions
GitHub Actions uses cron syntax in workflow files:
on:
schedule:
- cron: '0 6 * * 1' # Every Monday at 6 AM UTC
AWS CloudWatch Events
AWS uses a slightly modified cron syntax with 6 fields (includes year):
cron(0 12 * * ? *) # Every day at noon UTC
Kubernetes CronJobs
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup
spec:
schedule: "0 2 * * *" # 2 AM daily
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: my-backup-image
Node.js (node-cron)
const cron = require('node-cron');
cron.schedule('*/30 * * * *', () => {
console.log('Running every 30 minutes');
});
Common Mistakes
Timezone Confusion
Cron typically runs in the system timezone. On servers, this is often UTC. If you schedule 0 9 * * * thinking it's 9 AM local time but your server is in UTC, the job will run at 9 AM UTC — which could be 4 AM EST or 1 AM PST. Always verify your server's timezone with the date command.
Overlapping Executions
If a job takes longer than its schedule interval, multiple instances can run simultaneously. For example, a job scheduled every minute that takes 3 minutes to complete will have 3 overlapping instances. Use flock or similar mechanisms to prevent overlapping.
Day of Month vs Day of Week
When both day-of-month and day-of-week are specified (not *), standard cron treats them as OR — the job runs if either condition is met. 0 0 15 * 5 runs on the 15th of every month AND every Friday, not only on Fridays that fall on the 15th.
Forgetting PATH
Cron jobs run with a minimal environment. Commands that work in your terminal might fail in cron because the PATH is different. Always use full paths to executables: /usr/bin/python3 instead of python3.
Managing Cron Jobs
On Linux/macOS, manage your crontab with these commands:
# View current crontab crontab -l # Edit crontab crontab -e # Remove all cron jobs crontab -r # View another user's crontab (root only) crontab -u username -l
Conclusion
Cron expressions are a fundamental skill for any developer or system administrator. The five-field syntax (minute, hour, day of month, month, day of week) combined with special characters (*, /, -, ,) can express virtually any scheduling pattern. Start with simple patterns and gradually combine fields for complex schedules. When in doubt, always test your expressions before deploying.