Every Month Cron Expression
Runs on the 1st of every month at midnight.
0 0 1 * * in POSIX cron
Expression
0 0 1 * *Try it in the tester →Field Breakdown
How It Works
Day-of-month pinned to 1 — fires once per month at 00:00 on day 1.
Example Run Times
- Jan 1 00:00:00
- Feb 1 00:00:00
- Mar 1 00:00:00
- Apr 1 00:00:00
- May 1 00:00:00
Frequently Asked Questions
Is this the same as `@monthly`?
Yes — `@monthly` expands to `0 0 1 * *`.
0 0 1 * * in Quartz / Spring
Twelve firings a year, at 00:00 as each new month opens. Because month lengths differ, the gap between consecutive runs swings between 28 and 31 days — the only standard cadence whose interval isn't constant.
Quartz / Spring expression
0 0 0 1 * ?Try it in the tester →At 00:00:00 on day 1 of the month
Unix / POSIX equivalent: 0 0 1 * *
Field Breakdown
Using It with Quartz / Spring
Monthly triggers handle calendar-period chores: cutting a new table partition for the month ahead, rotating month-stamped archive buckets, snapshotting subscription states, or emailing the previous month's summary. The string goes into @Scheduled(cron = "0 0 0 1 * ?") or a Quartz CronTrigger unchanged. The 1st at midnight is a busy moment across the industry — billing systems, analytics platforms, and partner APIs all roll over at once — so if your job calls external services, consider sliding to a later hour or a different day where the date itself doesn't matter.
Quartz-Specific Notes
- →Lookback logic should not hardcode "30 days": the previous firing was 28, 29, 30, or 31 days ago depending on the month. Compute the window from the prior month boundary instead.
- →Moving the day-of-month past 28 changes the run count: a 29 fires 11 times in common years, a 30 skips February entirely, and a 31 fires only in the seven 31-day months. Quartz never substitutes the month's last day for a missing date — that's what L is for.
- →Day-of-month holds the literal here, so the mandatory ? goes to day-of-week: the 1st fires regardless of which weekday it is.
Frequently Asked Questions
What happens if I schedule day 31 in a 30-day month?
Nothing fires that month. 0 0 0 31 * ? runs only in January, March, May, July, August, October, and December — seven firings a year. For "end of every month" use the L token instead.
Can I run monthly on the 15th instead of the 1st?
Yes — 0 0 0 15 * ? fires at midnight on the 15th of every month. Any day 1-28 gives you a guaranteed twelve runs a year; 29 and above start skipping short months.
My monthly job hits a partner API that's overloaded on the 1st — options?
Shift the date (0 0 0 2 * ? for the 2nd) or the hour (0 0 5 1 * ? for 05:00 on the 1st). If the work only needs month-fresh data rather than the precise boundary, the 2nd at an off-peak hour is usually the pragmatic pick.
0 0 1 * * in AWS EventBridge
Twelve invocations a year: day-of-month is pinned to 1, so the rule fires at 00:00 UTC as each month opens. With day-of-month doing the work, the mandatory ? moves over to day-of-week.
AWS EventBridge expression
cron(0 0 1 * ? *)Try it in the tester →At 00:00 UTC on day 1 of the month
Unix / POSIX equivalent: 0 0 1 * *
Field Breakdown
Using It with AWS EventBridge
Month-start rules typically open billing cycles: generating invoices from a usage table, resetting per-tenant quota counters in DynamoDB, archiving the prior month's logs to Glacier, or kicking off a Step Functions workflow that emails statements. Create the rule with PutRule or model it as an aws_cloudwatch_event_rule in Terraform, then grant EventBridge permission to invoke the target. A monthly job has eleven months between a bug and its next natural retry, so wire a CloudWatch alarm on the target's error metric rather than waiting to notice missing invoices.
AWS-Specific Notes
- →Every month has a day 1, so this never skips — unlike day-of-month values above 28, which silently miss shorter months.
- →The firing instant is the month boundary in UTC; in US local time the run happens during the evening of the last day of the previous month.
- →Restricting the month field narrows this to specific months: cron(0 0 1 1,4,7,10 ? *) is the quarterly variant.
Frequently Asked Questions
How do I run monthly on the 15th instead of the 1st?
Replace the day-of-month value: cron(0 0 15 * ? *). Any value from 1 to 28 fires in all twelve months; 29, 30, and 31 are skipped in months that lack those dates.
What is the opposite of this — the last moment of the month?
EventBridge has a native token for that: cron(0 0 L * ? *) fires at 00:00 UTC on the final calendar day of each month, whether that is the 28th, 29th, 30th, or 31st.
Will my month-start data job see the new month or the old one?
It runs in the first minute of the new month in UTC, so queries for the completed month should target the previous calendar month. If your books close in a local timezone, schedule through EventBridge Scheduler with that timezone so the boundary matches your ledgers.
0 0 1 * * in GitHub Actions
Day-of-month 1 with everything else at defaults: twelve runs a year, each at 00:00 UTC as a new month opens. On GitHub Actions this is the heartbeat for anything keyed to the calendar month rather than the week or day.
GitHub Actions expression
0 0 1 * *Try it in the tester →At 00:00 UTC on day 1 of the month
Unix / POSIX equivalent: 0 0 1 * *
Field Breakdown
Using It with GitHub Actions
Defined as on: schedule: - cron: "0 0 1 * *" in a workflow on the default branch, the monthly tick drives calendar-cycle chores: opening the new month's planning milestone and tracking issue, rotating tokens on a monthly compliance schedule, snapshotting repository statistics into a dated file, or archiving the previous month's logs into a release asset. Where the 1st alone is too coarse, the day field takes a list — "0 0 1,15 * *" gives a twice-monthly rhythm from the same workflow.
GitHub-Specific Notes
- →Day 1 exists in every month, so this fires exactly 12 times per year — unlike schedules pinned to day 29, 30, or 31, which silently produce nothing in months that lack the date.
- →The weekday of the 1st rotates continuously; over a year this job will fire on every day of the week, so add a weekday check in the job if a human needs to act on the output.
- →With twelve ticks a year, a single missed one is a whole month of absent automation — make the job's success visible somewhere a human looks monthly.
Frequently Asked Questions
How do I run mid-month instead of on the 1st?
Set the day-of-month field directly: "0 0 15 * *" fires at 00:00 UTC on the 15th. Days 1 through 28 are safe in every month; 29-31 skip the months that don't reach them.
Is the monthly tick guaranteed, given how rarely it fires?
No — each tick is best-effort like any Actions schedule, and a missed one isn't retried until the next month. Add workflow_dispatch to the same on: block so you can fire the job by hand the moment you notice the gap.