Every 5 minutes is */5 * * * *. Daily at 2am is 0 2 * * *. Weekdays at 9 is 0 9 * * 1-5. First of the month is 0 0 1 * *. The five fields are minute, hour, day-of-month, month, day-of-week — and if you restrict both day fields at once, classic cron fires on either (see §3).
§1 · High-frequency schedules
| Expression | Meaning |
|---|---|
| * * * * * | every minute |
| */5 * * * * | every 5 minutes |
| */10 * * * * | every 10 minutes |
| */15 * * * * | every 15 minutes |
| */30 * * * * | every 30 minutes |
| 0 * * * * | every hour, on the hour |
| 0 */2 * * * | every 2 hours (00:00, 02:00, …) |
| 0 */6 * * * | every 6 hours (00:00, 06:00, 12:00, 18:00) |
| 30 */4 * * * | every 4 hours at minute 30 |
Step syntax */N means "every N units, starting at 0". */5 fires at :00, :05, :10 … — it does NOT mean "5 minutes after whenever it last ran".
§2 · Daily, weekly, monthly
Daily and business hours
| Expression | Meaning |
|---|---|
| 0 0 * * * | daily at midnight |
| 0 2 * * * | daily at 02:00 (classic backup slot) |
| 30 6 * * * | daily at 06:30 |
| 0 9,17 * * * | twice a day: 09:00 and 17:00 |
| 0 8-18 * * * | hourly, 08:00 through 18:00 |
| */10 9-17 * * 1-5 | every 10 min during business hours, weekdays |
Weekly
| Expression | Meaning |
|---|---|
| 0 9 * * 1-5 | weekdays at 09:00 |
| 0 22 * * 0,6 | Saturday and Sunday at 22:00 |
| 0 9 * * 1 | Mondays at 09:00 |
| 0 18 * * 5 | Fridays at 18:00 |
| 0 3 * * 0 | Sundays at 03:00 (maintenance window) |
Monthly and beyond
| Expression | Meaning |
|---|---|
| 0 0 1 * * | first day of every month, midnight |
| 0 6 1,15 * * | 1st and 15th at 06:00 (payroll pattern) |
| 0 0 28 * * | the 28th — the only always-safe "end of month" day |
| 0 0 1 1 * | January 1st (yearly) |
| 0 0 1 */3 * | first day of every quarter |
There is no portable "last day of month" in standard cron. The honest options: run on the 28th, run daily and check the date in your script, or use a scheduler with the non-standard L extension (Quartz and some libraries — not Vixie cron).
Shortcuts (widely supported, not POSIX)
| Expression | Meaning |
|---|---|
| @hourly | same as 0 * * * * |
| @daily | same as 0 0 * * * (alias @midnight) |
| @weekly | same as 0 0 * * 0 |
| @monthly | same as 0 0 1 * * |
| @reboot | once, at daemon start — great for agents/servers, not POSIX |
Not sure what an expression does? Paste it and get plain English + the next 10 run times, timezone-aware.
Open cron explainer →§3 · The three pitfalls that cause real incidents
- DOM + DOW is an OR, not an AND. In classic Vixie cron,
0 0 13 * 5does not mean "Friday the 13th" — it runs on every 13th AND every Friday. When both day fields are restricted, matching either one triggers the job. Restrict only one day field unless you want the union. - Cron runs in the daemon's timezone. A server in UTC firing
0 9 * * 1-5hits 4am in Bogotá, not 9. Checktimedatectl(or the platform's documented behavior), and preferCRON_TZwhere supported instead of doing timezone math in your head — DST will out-math you twice a year. - Sunday is 0 AND 7. Most crons accept both; scripts that parse crontabs often don't. Write
0for portability, and never write ranges that cross it (5-1) expecting wraparound.
§4 · Reading an expression in 10 seconds
Read right to left for the calendar, left to right for the clock: day-of-week and month tell you which days it can fire, day-of-month narrows (or ORs — see above), then hour and minute pin the time. Anything you can't parse in ten seconds, paste into the explainer — it decomposes every field and shows the next 10 real runs in your timezone, which is the fastest way to catch an OR-rule or timezone surprise before production does.
§5 · FAQ
What is the cron expression for every 5 minutes?
*/5 * * * * — step syntax in the minute field: fires at :00, :05, :10 … :55 every hour.
Why did my job run on days I didn't schedule?
You restricted both day-of-month and day-of-week. Classic cron treats that as an OR — either match fires. Keep one of the two fields as *.
What timezone does cron use?
The daemon's system timezone — not UTC by definition, not your machine. Verify on the host; use CRON_TZ where supported.
Are @daily and @reboot standard?
They're Vixie extensions — near-universal on Linux crontabs, absent from many library implementations. Expand to five-field form when portability matters.