Every Year Cron Expression
Runs once per year — January 1 at midnight.
0 0 1 1 * in POSIX cron
Expression
0 0 1 1 *Try it in the tester →Field Breakdown
How It Works
Pinned to January 1 at 00:00 — fires exactly once per year.
Example Run Times
- 2026-01-01 00:00:00
- 2027-01-01 00:00:00
- 2028-01-01 00:00:00
- 2029-01-01 00:00:00
- 2030-01-01 00:00:00
Frequently Asked Questions
Is this the same as `@yearly` / `@annually`?
Yes — both Vixie-cron aliases expand to `0 0 1 1 *`.
0 0 1 1 * in Quartz / Spring
One firing per year: 00:00 on January 1, when both day-of-month and month are pinned to 1. No other standard cadence makes a single trigger this consequential — miss it and the next natural opportunity is twelve months away.
Quartz / Spring expression
0 0 0 1 1 ?Try it in the tester →At 00:00:00 on day 1 of the month in Jan
Unix / POSIX equivalent: 0 0 1 1 *
Field Breakdown
Using It with Quartz / Spring
Annual triggers reset year-scoped state: rolling invoice or ticket number sequences into a new prefix, opening the new fiscal-year ledger, archiving the completed year's data to cold storage, or regenerating year-stamped report templates. Wire it with @Scheduled(cron = "0 0 0 1 1 ?") or a Quartz CronTrigger. Given the stakes of a once-a-year slot, surround it with belt and suspenders: an explicit misfire instruction so an outage over New Year's doesn't cost a full year, plus monitoring that alerts if January 1 passes without a completed run.
Quartz-Specific Notes
- →The month field counts 1-12 (names JAN-DEC also parse), so the second 1 in the date section is January — not Monday, which is a day-of-week concept.
- →Quartz optionally takes a seventh field for the year: 0 0 0 1 1 ? 2030 fires exactly once ever, at midnight opening 2030 — the cleanest way to express a one-shot future task in cron form.
- →The trigger's timezone decides when the year actually starts; a fleet spanning UTC and local-time JVMs will "start the year" hours apart unless every trigger pins the same zone.
Frequently Asked Questions
How do I notice if the January 1 run never happened?
With 364 days until the next natural firing, a missed annual run deserves explicit monitoring: alert if the job's success marker is absent by January 2, and avoid MISFIRE_INSTRUCTION_DO_NOTHING here — it would silently postpone a missed New Year's run by a full year.
How do I schedule something for one specific date and never again?
Use the optional year field: 0 0 0 15 6 ? 2027 fires at midnight on June 15, 2027, exactly once. After that date passes the trigger simply has no future fire times.
Can I run yearly on a date other than January 1?
Pin different values: 0 0 0 1 4 ? fires every April 1, and 0 0 9 31 12 ? fires at 09:00 every December 31. Any fixed day-month pair gives one run per year.
0 0 1 1 * in AWS EventBridge
January 1st at 00:00 UTC, and then nothing for another 365 or 366 days. Both day-of-month and month are pinned to 1, making this the sparsest recurring schedule most accounts will ever run — and the one entry where EventBridge's sixth field, the year, deserves a closer look.
AWS EventBridge expression
cron(0 0 1 1 ? *)Try it in the tester →At 00:00 UTC on day 1 of the month in Jan
Unix / POSIX equivalent: 0 0 1 1 *
Field Breakdown
Using It with AWS EventBridge
Annual rules handle work tied to the calendar year: rolling sequence numbers or invoice prefixes that embed the year, creating the new year's partition in a data lake, archiving the completed year's records to cold storage, or resetting annual leave balances in an internal HR tool. The trailing * keeps it firing every year; substituting a specific year such as cron(0 0 1 1 ? 2030) turns the rule into a one-shot that fires once and never again. For one-time events EventBridge Scheduler is often cleaner still, with its at(2030-01-01T00:00:00) one-time expression and the option to auto-delete the schedule after completion.
AWS-Specific Notes
- →EventBridge is the only flavor on this site that REQUIRES a year field — Quartz treats a seventh year field as optional, and POSIX cron has no equivalent, which is why the conversion appends the *.
- →Midnight UTC on January 1st is still December 31st evening across the Americas; New Year processing for US-local books should either shift the hour or use Scheduler with a timezone.
- →With a single firing per year, test the target by invoking it manually with a synthetic event rather than waiting for production proof.
Frequently Asked Questions
Can I use the year field to schedule something that runs only once?
Yes — pin all the fields, including a concrete year: cron(0 0 1 1 ? 2030) fires at 00:00 UTC on 2030-01-01 and never matches again. EventBridge Scheduler's at() expressions do the same job with optional automatic cleanup of the spent schedule.
How do I run on a different anniversary, say July 4th each year?
Set day-of-month and month accordingly: cron(0 0 4 7 ? *). Month accepts numbers 1-12 or names like JUL, so cron(0 0 4 JUL ? *) is equivalent and more readable.
0 0 1 1 * in GitHub Actions
Month pinned to January, day pinned to the 1st: a single run per year at 00:00 UTC on New Year's Day. This is the sparsest schedule 5-field cron can express, and on GitHub Actions its biggest enemy is not the syntax but the platform's inactivity policy.
GitHub Actions expression
0 0 1 1 *Try it in the tester →At 00:00 UTC on day 1 of the month in Jan
Unix / POSIX equivalent: 0 0 1 1 *
Field Breakdown
Using It with GitHub Actions
It sits in workflow YAML as on: schedule: - cron: "0 0 1 1 *" and covers genuinely annual chores: bumping copyright years across source headers, running a full dependency-license audit, archiving the closed year's data, or opening a year-in-review tracking issue. Always pair it with workflow_dispatch in the same on: block — with one natural firing per year, a manual trigger is the only practical way to test the job and the only recovery path if the January tick is missed.
GitHub-Specific Notes
- →On public repositories, schedules auto-disable after 60 days without repository activity — far shorter than the 365-day gap between this schedule's runs. A quiet public repo will have this workflow suspended long before January 1 arrives unless commits or manual re-enabling keep it alive.
- →00:00 UTC on January 1 is still New Year's Eve across the Americas — 19:00 December 31 in New York under EST — while Tokyo sees it at 09:00 on the 1st.
- →One matching instant per year means a skipped or failed run has no second chance for twelve months; treat the run's absence in early January as an incident, not noise.
Frequently Asked Questions
Will an annual schedule actually fire on a repo nobody touches?
On a public repository, probably not — 60 days of inactivity disables scheduled workflows, and an annual job gives you roughly ten silent months for that to happen. Private repositories are not subject to the inactivity disable, so the schedule survives there.
How do I run yearly on December 31 instead of January 1?
Pin the other end of the calendar: "0 0 31 12 *" fires at 00:00 UTC on December 31. Both dates exist every year, so either expression yields exactly one run annually.