Skip to the tool
DevToolBench

Cron Every Month

Monthly and quarterly jobs, last day included.

minute hour day-of-month month day-of-week

At 00:00 on day-of-month 1.

Fields

minute
0
hour
0
day of month
1
month
*
day of week
*

Next 5 runs

Times shown in your own timezone.

Common schedules

Monthly schedules

ExpressionWhat it doesCopy
0 0 1 * *First of the month, at midnightAt 00:00 on day-of-month 1.
0 3 15 * *Mid-month, away from the billing runAt 03:00 on day-of-month 15.
0 0 28-31 * *Every candidate for the last dayAt 00:00 on every day-of-month from 28 through 31.
0 0 1 */3 *Quarterly, on the firstAt 00:00 on day-of-month 1 in January, April, July and October.

Everything runs in your browser. Nothing you type is sent to a server.

Found a bug in this tool? Report it.

The monthly schedule

A cron every month schedule fires once per calendar month, and the conventional form puts it at midnight on the 1st. Crontab also accepts @monthly, which expands to exactly those fields. The 1st is not an arbitrary convention: it is the only day number that exists in all twelve months, so it is the only one where a monthly schedule really means twelve runs a year.

Day numbers above 28 are a lottery

Pin a job to the 31st and it runs in January, March, May, July, August, October and December. The other five months have no 31st, so the schedule simply does not match, and nothing anywhere reports a missed run. The 30th loses February. The 29th loses February in three years out of four. Only the 1st through the 28th are safe in every month, and only the 1st is safe and obvious.

If a job must run near the end of the month, say so explicitly rather than hoping the day number exists.

Getting the last day without an L

The Quartz dialect used by Java schedulers has a character for the last day of the month. Crontab does not, and adding one is not on offer. The pattern that works splits the decision in two: the schedule fires on every day that could be the last one, and the script checks whether today actually is.

0 0 28-31 * * [ "$(date -d tomorrow +\%d)" = "01" ] && /opt/app/close-month.sh

The date test asks whether tomorrow is the first, which is true exactly once per month regardless of length. Percent signs need escaping inside a crontab line, which is the detail that costs people an afternoon. On systems without GNU date, the equivalent test uses a different flag, so check yours before trusting the line.

Quarters and half years

A step in the month field counts from January. Three gives you January, April, July and October, which are the calendar quarters, and six gives you January and July. That is the right answer when your year starts in January and the wrong one when it does not — a financial year beginning in April needs the four months listed explicitly, because the step has no way of knowing where you would like it to start.

Twelve chances a year to notice

A monthly job gets twelve attempts a year, so a bug in one can survive a whole quarter before anyone connects it to the schedule. Test the line by running the command by hand first, then watch the next five runs the panel above computes and check that the dates are the ones you expected — a schedule that skips five months a year looks perfectly healthy in a log until someone asks for the missing report.

Where monthly work belongs

A monthly job is usually a close, an invoice run or a retention sweep, and all three want the timezone question settled before anything else, exactly as a daily midnight job does. If the work is weekly reporting that happens to be summarised monthly, a Monday schedule is the honest expression of it. Read the finished line back with the cron expression generator, where the next five runs will show you immediately whether the day number you chose exists as often as you expected.

Frequently asked questions

How do I schedule a job for the last day of the month?

Not with the schedule alone. Crontab has no character for the last day, so the working pattern is to fire on the 28th through the 31st and let the script decide. A one-line test comparing tomorrow's day number against 1 tells you today is the last day, and the script exits early on the other three mornings.

Does the monthly shortcut do anything the fields do not?

No. It expands to minute 0, hour 0, day 1, every month, every weekday, which is precisely what the explicit form says. Use whichever reads better in your crontab, but do not expect the shortcut to know anything about month lengths, because it does not.

How do I run something once a quarter?

Put a step of three in the month field alongside a fixed day. The count starts at January, so you get January, April, July and October — the calendar quarters. If your financial year starts elsewhere, list the four months explicitly instead, because the step always counts from the beginning of the field.

Why did my job on the 31st skip several months?

Because those months do not have a 31st. Cron matches a real date, so a schedule pinned to the 31st runs seven times a year and silently misses the other five. Any day number above 28 has this problem to some degree, which is why the 1st is the conventional choice for monthly work.

Related tools

Updated