FreeAI.DevTools

Cron: Monthly

The cron expression for "monthly", what each field means, and the next run times on your clock.

What is the cron expression for once a month?

0 0 1 * * runs at midnight on the first day of every month. Minute 0, hour 0, and day of month 1 pin the moment, with wildcards for month and day of week. That is twelve runs per year, the cadence billing cycles and monthly archive rotation are built on.

0 0 1 * *

At 12:00 AM, on day 1 of the month

Next 5 runs (your timezone)

First-of-month work, and a field-order trap

The 1st at midnight is when subscription billing runs charge renewals, finance jobs close out the prior month's ledger, databases create next month's partitions, and archival jobs compress and ship the previous month's data to cold storage. Anchoring to day 1 gives these jobs a complete prior month to operate on, which is exactly what invoicing and reporting need.

Watch the field order when writing it by hand. Day of month is field three and month is field four, so 0 0 1 * * is monthly on the 1st, while the transposed 0 0 * 1 * runs every single day of January and never otherwise. Both parse without complaint, and only one of them sends invoices.

There is no last-day-of-month in POSIX cron

Quartz has an L token for the last day of the month; five-field cron does not, and 0 0 31 * * only fires in the seven months that actually have a 31st. The standard workaround schedules 0 0 28-31 * * and lets the script decide: exit early unless tomorrow is the 1st, testable in shell as [ "$(date -d tomorrow +%d)" = "01" ] on GNU systems.

For most month-end requirements, we suggest sidestepping the problem: run on the 1st and process the month that just ended. The data is complete, the expression stays trivial, and the job no longer depends on calendar arithmetic inside a shell one-liner.

Frequently asked

How do I run a cron job on the last day of the month?
Five-field cron has no last-day token, so schedule 0 0 28-31 * * and have the command exit unless tomorrow is the 1st, for example with date -d tomorrow +%d on GNU date. Alternatively run on the 1st and operate on the previous month's data.
Will 0 0 31 * * run every month?
No. It only fires in months that contain a 31st: January, March, May, July, August, October, and December. February, April, June, September, and November are skipped entirely, which makes it a poor stand-in for month-end.
Is @monthly equivalent to 0 0 1 * *?
Yes. crontab(5) defines @monthly as 0 0 1 * *, midnight on the first of the month in local time. The nickname is fine in a classic crontab, but schedulers like Kubernetes CronJobs and GitHub Actions expect the five-field form.

More in this series

// The subscription desk

The Inference Report

The weekly briefing for AI engineers: model releases, pricing moves, benchmarks, and the news that changes what you should build with and what it costs. Every Tuesday, 5-minute read. No fluff.

Join AI engineers who stopped overpaying for tokens. Unsubscribe anytime.