0 0 1 1,4,7,10 *
At 00:00 on day 1 of the month in January, April, July and October
Field by Field
| Field | Value | Matches |
|---|---|---|
| Minute | 0 | 0 |
| Hour | 0 | 0 |
| Day of month | 1 | 1 |
| Month | 1,4,7,10 | 1, 4, 7, 10 |
| Day of week | * | every day |
Four Runs a Year
The month field lists 1, 4, 7 and 10, and the day-of-month field pins each to the 1st. That is the calendar quarter — which is not necessarily your fiscal quarter.
| Fiscal year starts | Quarter months |
|---|---|
| January | 1,4,7,10 |
| February | 2,5,8,11 |
| April (UK, Japan) | 4,7,10,1 |
| July (Australia) | 7,10,1,4 |
| October (US federal) | 10,1,4,7 |
Step Syntax Also Works
0 0 1 */3 * is equivalent to 1,4,7,10 because the step divides the month range from
its start. For any fiscal year that does not begin in January, the explicit list is the only
correct form.
Quarterly Jobs Run Rarely Enough to Rot
Four executions a year is not enough to notice a broken dependency, an expired credential or a renamed table. Run the job against staging monthly even though production runs quarterly.
Time Zones
Standard crontab evaluates in system local time. Vercel Cron, GitHub Actions, Kubernetes
CronJobs and AWS EventBridge all evaluate in UTC. If converting your local time crosses
midnight, the day-of-week field shifts too — weekdays at 5pm in UTC-07:00 is
0 0 * * 2-6, not 0 0 * * 1-5.
The Day-Field Trap
When both the day-of-month and day-of-week fields are restricted, cron matches either,
not both. 0 0 13 * 5 runs on every 13th *and* every Friday — not Friday the 13th. Leave
one of them as * unless you genuinely want the union.
Other Common Schedules
| Expression | Runs |
|---|---|
* * * * * | Every minute |
*/5 * * * * | Every 5 minutes |
*/15 * * * * | Every 15 minutes |
0 * * * * | Every hour, on the hour |
0 0 * * * | Every day at midnight |
0 9 * * * | Every day at 9am |
0 9 * * 1-5 | Weekdays at 9am |
0 9 * * 1 | Every Monday at 9am |
Making the Job Safe
- Assume double firing. DST transitions, restarts and retries all cause it. Make the job
- Assume overlap. Cron starts the next run whether or not the last one finished. Take a
- Avoid
:00. Every hourly job on the internet fires at the top of the hour; a random
- Log the start and end. A cron job that silently stops running is invisible until