Cron Expression Guide for Developers
Cron looks simple until a production task runs at the wrong hour, never runs at all, or fires twice because someone misunderstood the scheduler. This guide explains how five-field cron expressions work, where teams make mistakes, and how to validate schedules before they reach real systems.
1. What a Cron Expression Represents
A cron expression describes a recurring schedule by splitting time into fields. The common Unix format uses five fields:
minute hour day-of-month month day-of-week
* * * * *
| Field | Range | Example |
|---|---|---|
| Minute | 0-59 | */15 |
| Hour | 0-23 | 9 |
| Day of month | 1-31 | 1 |
| Month | 1-12 | 1,4,7,10 |
| Day of week | 0-7 | 1-5 |
2. Core Syntax You Actually Need
- * means “every possible value” for that field.
- 1,3,5 means a list of explicit values.
- 1-5 means a range.
- */15 means every 15 units.
- 1-10/2 means every 2 units inside the range 1 through 10.
# Every minute * * * * * # Every day at 02:30 30 2 * * * # Every weekday at 09:00 0 9 * * 1-5 # Every 15 minutes */15 * * * * # At 08:00 on the first day of every month 0 8 1 * *
3. The Most Common Cron Mistakes
⚠️ Confusing day-of-month with day-of-week
The third field is the date in the month, while the fifth field is the weekday. Mixing them up creates schedules that look correct but never match the intended calendar.
⚠️ Forgetting scheduler differences
Classic Unix cron, Kubernetes CronJob, Quartz, cloud schedulers, and CI tools do not all support the same syntax. Some expect 5 fields, some 6 or 7, and some interpret weekdays differently.
⚠️ Ignoring time zones
A valid expression can still run at the wrong business hour if the host, container, or scheduler uses UTC while your team thinks in local time.
⚠️ Writing expressions you cannot explain
If a teammate cannot read the expression and confirm the next few run times, the schedule is too opaque to trust in production.
4. Examples Developers Use Often
| Use case | Expression | Notes |
|---|---|---|
| Health check every 5 minutes | */5 * * * * | Simple polling, keep the task lightweight. |
| Weekday morning report | 30 9 * * 1-5 | Useful for office-hours automations. |
| Monthly billing summary | 0 8 1 * * | Runs at 08:00 on the first day of the month. |
| Nightly cleanup job | 0 2 * * * | Good default for low-traffic windows. |
| Twice-daily sync | 0 2,14 * * * | Runs once overnight and once midday. |
5. Test the Next Run Times, Not Just the String
The safest way to review a cron expression is to generate the next few execution times and compare them with the plain-English requirement. A string such as 0 9 * * 1-5 is much easier to trust when you can verify that the next runs really are weekdays at 09:00 in the expected timezone.
Requirement: "Run every weekday at 09:00" Draft cron: 0 9 * * 1-5 Check the next runs: - Mon 09:00 - Tue 09:00 - Wed 09:00 - Thu 09:00 - Fri 09:00 If the preview shows Saturday or midnight UTC, the schedule is wrong or the scheduler timezone is different from your expectation.
6. Production Checklist Before You Ship
- Confirm whether your platform expects 5 fields or a different cron flavor.
- Write down the intended timezone explicitly.
- Preview the next 5 to 10 run times.
- Check what happens on weekends, month boundaries, and daylight-saving changes.
- Make sure the task is idempotent in case the scheduler retries or overlaps.
- Document the schedule in plain language next to the expression.
7. A Better Workflow Than Hand-Writing Cron
Many cron bugs are not syntax errors. They are understanding errors. A visual builder reduces those mistakes by separating each field, offering common presets, and showing future execution times before you copy the final string into crontab, Docker, Kubernetes, or CI settings.
Use our Cron Expression Builder to assemble schedules, preview the next runs, and copy the final expression with fewer surprises.