My Tool Studio
Developer Tools·4 min read

How to Read a Cron Expression, Field by Field

Learning how to read a cron expression takes about five minutes and saves entire mornings. Five space-separated fields, minute, hour, day of month, month, and day of week, describe when a job fires, and a single swapped value moves your deploy from 9 AM to 3 AM without a word of complaint from any tool in the pipeline. This guide decodes the fields in order, works through 0 9 * * 1-5 as a full example, lists the schedules worth memorizing, and covers the mistakes that put jobs on the wrong clock.

Cron Expres…{"id": 4"ok": true}

The deploy that fired at three in the morning

Timezone assumptions meet crontab.

A team schedules a nightly build for what they believe is 9 PM local, gets paged at 3 AM, and spends the next standup arguing about whose fault it was. The expression was valid. The parser accepted it. The job simply ran on a server that keeps UTC while everyone reading the crontab was thinking in their own local time.

Cron never warns you about intent. The only defense is reading the expression back correctly and checking the concrete run times before committing, which is exactly what a next-runs list is for.

Reading an expression left to right

Always read the five fields in the same order: minute, hour, day of month, month, day of week. The most common misread is reversing the first two, since humans say nine thirty but cron writes 30 9.

Paste any expression into the Cron Expression Generator and it shows a Plain English summary plus the next run times, 10 by default, in the time zone you choose, each with a Copy button. If the run list doesn't match the sentence in your head, one of the fields isn't saying what you think it says. Some schedulers, such as Quartz and Spring, put a seconds field first; set Syntax to Quartz for those, or type a six-field expression and the seconds value appears in the summary.

The five cron fields explained

Each position accepts a value, a range, a list, or a step. If you'd rather not type the whole string, the Build it field by field section gives each position its own box with its allowed range shown, and the full expression above updates as you edit.

  • Minute, 0 to 59. A bare 15 means at minute 15; */10 means every ten minutes.
  • Hour, 0 to 23, on the 24-hour clock. 0 is midnight and 14 is 2 PM.
  • Day of month, 1 to 31. Beware values above 28 in February, since the job simply skips months without that date.
  • Month, 1 to 12. Ranges like 6-8 confine a schedule to summer.
  • Day of week, 0 to 6 starting from Sunday, with most systems also accepting 7 for Sunday. Ranges like 1-5 mean weekdays.

Worked example: what 0 9 * * 1-5 really says

Read it field by field. Minute 0, hour 9, every day of month, every month, days of week 1 through 5. In plain English: at 09:00 on Monday through Friday, the standard business-hours schedule for reports and syncs.

Enter it in the generator, or click the Weekdays at 9 AM preset, set the zone to UTC, and the next 10 runs land at 09:00 UTC on consecutive weekdays, skipping every Saturday and Sunday. That skip is your visual proof that the 1-5 range took effect, and switching the zone menu shows the same runs on whatever clock your server keeps.

Common cron schedules worth keeping on hand

A handful of expressions cover most scheduling needs, and the generator includes these among its one-click presets:

  • * * * * * runs every minute, useful mostly for testing that cron itself works.
  • */5 * * * * runs every five minutes, the classic health-check cadence.
  • 0 * * * * runs at the top of every hour.
  • 0 0 * * * runs daily at midnight, the default home for cleanup jobs.
  • 0 8 * * 1 runs Mondays at 08:00, a weekly report slot.
  • 0 0 1 * * runs on the first of every month, for billing and rollups.
  • 0 0 1 */3 * runs quarterly, at midnight on the first day of January, April, July and October.

Mistakes that corrupt your cron schedules

Most scheduling bugs trace back to one of these:

  • Swapping minute and hour. 9 0 * * * fires at 00:09, not 09:00, and both parse without complaint.
  • Assuming local time. The daemon uses the server's clock, and containers overwhelmingly default to UTC.
  • Setting both day of month and day of week. Classic cron treats the two restrictions as either-or, so 0 0 13 * 5 fires on the 13th and on every Friday, not only on Friday the 13th. The Plain English summary spells this out with an or.
  • Writing impossible steps like */70 in the minute field, which some implementations reject and others quietly reinterpret.
  • Scheduling between 1 and 3 AM local in zones with daylight saving, where a job can run twice or not at all on transition nights.

Tips before you commit a schedule

Always check the next 10 runs before the expression reaches a crontab or a CI config. The list catches wrong-hour and wrong-day bugs that a syntax check never will, because the expression is valid, just wrong.

Leave the Plain English summary as a comment above the crontab line, and standardize your fleet on UTC. Both habits cost seconds and remove the two most common sources of scheduling confusion.

Tools that pair well with schedule debugging

Once a job runs, you'll often compare its logged epoch timestamps against the expected trigger times. The Unix Timestamp Converter turns those raw seconds into readable UTC dates so the comparison is honest.

And when you're grepping logs to confirm the job actually fired on schedule, the Regex Tester helps you build the timestamp-matching pattern against a pasted log sample before you bake it into a script.

Try it now

Open Cron Expression Generator

The tool is one click away. No sign up, no upload, no payment.

Open Cron Expression Generator