Cron Parser How to Read Crontab Schedules Without the Manual — and Why 0 0 * * 0 Is Not the Same as @weekly
You found a cron expression in a server config. Does it run at midnight every day, or midnight on Sundays? Here's how to decode cron syntax without the reference card.
You SSH into a production server and check the crontab: 30 2 * * 1 /usr/bin/backup.sh. You know this runs a backup script. But when? 2:30 AM every day? 2:30 AM on Mondays? 2:30 AM on the 1st of every month? You could dig through the cron man page. Or you could paste the expression into a cron parser and see "At 02:30 AM, every Monday" plus the next ten execution times.
Cron syntax is deceptively simple — five fields, each with specific rules. But the special characters and overlapping day-of-month/day-of-week behavior create edge cases that trip up even experienced developers. Here is how to read any cron expression in seconds.
The Five Fields, Explained in Plain English
A cron expression is five space-separated fields: minute (0-59), hour (0-23), day of month (1-31), month (1-12), day of week (0-7) — where 0 and 7 both mean Sunday. Each field can be a specific number, a wildcard (* means "every"), a range (1-5 means "1 through 5"), a list (1,3,5), or a step value (*/15 means "every 15").
The most common expressions: */5 * * * * = every 5 minutes. 0 * * * * = every hour at the top of the hour. 0 9 * * 1-5 = 9:00 AM, Monday through Friday. 0 0 1 * * = midnight on the 1st of every month. 0 0 * * 0 = midnight every Sunday.
The day-of-month vs day-of-week trap: When both day-of-month and day-of-week are specified (not *), cron runs when either condition matches. 0 0 13 * 5 runs at midnight on every Friday AND on the 13th of every month — not just "Friday the 13th." This is the most common cron scheduling bug. If you want "Friday the 13th," you need logic inside the script, not in the cron expression.
Step Values: The Most Misunderstood Feature
*/5 in the minute field means "every 5 minutes" — specifically, at minutes 0, 5, 10, 15, 20, ... 55. It does NOT mean "every 5 minutes starting from whenever the system booted." Cron always starts counting from the beginning of the range. */7 means minutes 0, 7, 14, 21, 28, 35, 42, 49, 56 — an uneven pattern that most people do not intend. Use step values that divide evenly into the range (2, 3, 4, 5, 6, 10, 12, 15, 20, 30) unless you have a specific reason for an uneven pattern.
You can also combine ranges with steps: 1-30/10 in the minute field means minutes 1, 11, 21. This is useful for offsetting jobs — running at 1, 11, 21, 31, 41, 51 minutes past the hour instead of the more common 0, 10, 20, 30, 40, 50. Offsetting reduces load spikes when hundreds of cron jobs all fire at minute 0.
Using a Cron Parser as a Safety Check
Before you save a crontab, paste the expression into a cron parser. The human-readable description tells you what the expression actually does — not what you intended it to do. The next-execution list shows you exactly when the job will fire in the next few hours or days. If the times look wrong, the expression is wrong.
This 5-second check catches the most common mistakes: confusing day-of-month with day-of-week, using step values that produce unexpected patterns, forgetting that cron uses the server's timezone (not UTC necessarily), and accidentally scheduling jobs for times that do not exist (2:30 AM during daylight saving spring-forward).
Parse your cron expressions at free cron parser — paste, read, verify, save. Five seconds that prevents a 3 AM production incident.
Tools mentioned in this article
Cron Expression Parser
Parse cron expressions and see when your scheduled jobs will run. Get human-readable descriptions and the next 10 execution times. Supports all 5-field standard cron syntax — no server needed.
Unix Timestamp Converter
Convert Unix timestamps to human-readable dates and vice versa. Supports seconds and milliseconds. Shows UTC and local time side by side. Pick a date to get its timestamp.
Hash Generator
Generate SHA-1, SHA-256, SHA-384, and SHA-512 hashes from any text. Also supports MD5 for legacy checks. Compare two hashes side by side to verify file integrity.
