Cron on the first day of the month: 0 0 1 * *
0 0 1 * * runs once a month, at midnight on the first day. It is precisely what @monthly expands to, and the 1st exists in every month so no run is ever skipped.
At a glance
- Expression
- 0 0 1 * *
- Fires
- 12 times a year, once per calendar month.
- Restricted fields
- Minute, hour and day of month pinned. Month and day of week are open.
- Equivalent macro
- @monthly, which expands to exactly 0 0 1 * *.
- Day matched
- 1. Every month has a first day, so the run never disappears.
- Collision at midnight
- On 1 January this fires alongside @yearly, @monthly, @daily and, if it is a Sunday, @weekly.
In detail
The first of the month is the only day of month value that is guaranteed to exist in every month, which makes it the safe choice for a monthly schedule. Pin the minute, the hour and the day, leave the month open so it repeats, and leave the day of week open so the OR rule never comes into play.
@monthly is a shorthand for this exact expression, so a crontab line starting @monthly and a line reading 0 0 1 * * are the same schedule. The macro is more readable and slightly less flexible, since there is no way to shift it to a different hour or a different day without writing the fields out.
Monthly billing, monthly reports and monthly archives all tend to land here, which means the first of the month at midnight is the busiest minute of the busiest hour of the busiest day on many systems. Moving to 0 4 1 * * or 30 2 1 * * costs nothing and gets the job out of the crush.
A job that runs on the 1st and reports on the previous month has one detail to get right: at 00:00 on 1 March the previous month is February, and computing it as the current month minus one is exactly the kind of arithmetic that breaks on 1 January. Derive the boundaries from the date, and test the January case explicitly.
Examples
0 0 1 * *@monthly /opt/app/bin/invoice.sh >> /var/log/invoice.log 2>&130 4 1 * * /opt/app/bin/invoice.sh >> /var/log/invoice.log 2>&104:30 on the first, same twelve runs a year.
Things that catch people out
- Adding a day of week restriction breaks the intent. 0 0 1 * 1 fires on the 1st and on every Monday, because the two date fields are combined with OR.
- @monthly cannot be moved off midnight. If you need a different time, write the five fields out.
- A report covering last month must handle the January run, where last month is in the previous year.
Try it: Cron Expression Parser
Paste any five or six field expression to get a plain English description, a per field breakdown and the next run times in your local time.
Cron Expression Parser
LOCAL · Browser-OnlyParse cron expressions and see the next scheduled run times
Supports 5-field (minute hour day month weekday), 6-field (with seconds), named values (JAN, MON), and @macros (@daily, @hourly, ...)
Use the dropdowns below to build your cron expression visually, or type a custom value in each field.
Human-Readable Description
Every 5 minutes
Field Breakdown
| Field | Allowed | Value | Meaning |
|---|---|---|---|
| Minute | 0-59 | */5 | every 5 minute(s) |
| Hour | 0-23 | * | every hour |
| Day of Month | 1-31 | * | every day of month |
| Month | 1-12 | * | every month |
| Day of Week | 0-7 | * | every day of week |
Related cron expressions
All cron expressions →Cron on the 1st and 15th: 0 0 1,15 * *
0 0 1,15 * * runs on the first and fifteenth of every month, 24 times a year. The gaps run from 13 to 17 days, so it is not a fortnight.
Cron on the last day of the month: the L workaround
This parser rejects the Quartz L character, so the last day of the month needs a date range plus a script guard that checks whether tomorrow is the 1st.
Cron every quarter: 0 0 1 */3 *
0 0 1 */3 * runs on the 1st of January, April, July and October, four times a year. Shift it with 2/3 for a fiscal year starting in February.
Cron macros: @daily, @weekly, @monthly and the rest
Seven macros expand to ordinary five field expressions, and @reboot has no scheduled time at all. Here is exactly what each one becomes.
Cron on the 31st: 0 0 31 * * only fires seven times a year
0 0 31 * * runs only in months that have 31 days, so it fires seven times a year, not twelve. The same trap hits day 30 and day 29.
Cron on the first Monday of the month: the OR rule trap
0 9 1-7 * 1 does not mean the first Monday. Because both date fields are restricted, it fires on days 1 to 7 and on every Monday as well.
Tools for this
- Cron Expression Parser Free online cron expression parser - parse cron expressions and see the next scheduled run times
- Crontab Generator Free online crontab generator - build cron expressions visually with an intuitive interface