Skip to content
Webmaster Tools

Cron once a year

To run a cron job once a year use @yearly (or @annually), which is 0 0 1 1 *, midnight on 1 January. Other dates, leap days, and the GitHub Actions and AWS forms.

Cron expression
0 0 1 1 *
See the next run times

The expression

0 0 1 1 *

Runs once a year, at 00:00 on 1 January. The @yearly and @annually macros mean exactly this.

Field Value Meaning
Minute 0 at minute 0
Hour 0 at midnight
Day of month 1 the 1st
Month 1 January
Day of week * any day of the week

Standard cron has no year field, so "once a year" means one fixed date in the month and day-of-month fields. To run on any other date, change those two: 30 June at 18:00 is 0 18 30 6 *.

Variants

Schedule Expression
1 January at 6am 0 6 1 1 *
31 December at 23:00 0 23 31 12 *
1 April (start of a fiscal year) 0 0 1 4 *
Twice a year 0 0 1 1,7 *
Every quarter 0 0 1 1,4,7,10 *
Every month 0 0 1 * *
29 February (leap years only) 0 0 29 2 *

0 0 29 2 * really does run only every four years (more precisely, in leap years), because cron skips dates that don't exist. That's correct behaviour, but rarely what a "yearly on the 29th" job wants. Use the 28th, or 1 March.

Where to write it

  • crontab (Linux, macOS): @yearly command or 0 0 1 1 * command in crontab -e, in the server's time zone. A server that is off or rebooting at midnight on New Year's Day misses the run for a whole year; anacron (an /etc/anacrontab line with a period of 365 days) or a systemd timer with OnCalendar=yearly and Persistent=true catch up instead.
  • GitHub Actions: cron: '0 0 1 1 *' in UTC, so it fires on the afternoon or evening of 31 December across the Americas. GitHub disables scheduled workflows in public repositories after 60 days without activity, so in a quiet repo a yearly workflow will usually be off by the time it's due.
  • Kubernetes CronJob: schedule: "@yearly" or "0 0 1 1 *", with timeZone: so New Year is your New Year.
  • AWS EventBridge: cron(0 0 1 1 ? *). EventBridge has a sixth field for the year, so a one-off on a single date is also possible: cron(0 0 1 1 ? 2027).

Common mistakes

  • 0 0 * 1 * runs every day in January.
  • 0 0 1 * * is monthly, not yearly.
  • Year-boundary bugs in the job itself. A job at 00:00 on 1 January that computes "this year" gets the new year. If it should close out the year that just ended, compute the previous year, or run at 0 23 31 12 *.
  • Testing once a year. Run the command by hand after every change; you won't see the schedule fire for months.

See the next runs in the Cron Expression Parser.