0 0 1 1 * runs a job once a year, at 00:00 on January 1. Minute and hour are 0, the day of month is 1 and the month is 1. @yearly and @annually are shortcuts for the same line in most crons, and this tool expands them to it.
When it fires
Checked on October 14, 2026, the next five runs are:
Jan 1 2027 Jan 1 2028 Jan 1 2029 Jan 1 2030 Jan 1 2031 (all at 00:00)
Any other date works the same way, day of month first and then month: 0 9 15 4 * runs at 09:00 every April 15. Be careful with February 29: 0 0 29 2 * runs only in leap years, next on February 29, 2028 and then 2032.
Missed runs stay missed
Cron starts a job only if the machine is up at that minute. A server that is down or asleep at midnight on January 1 skips the year’s only run, and cron doesn’t catch up later. A systemd timer with Persistent=true does: when the timer starts again, it runs the job once if a scheduled time passed while it was off.
Whose January 1?
The server’s timezone, and UTC on GitHub Actions and EventBridge rules. Midnight UTC on January 1 is still December 31 in the Americas, so a job that rolls over a year counter or archives last year’s data should pin its zone: CRON_TZ in a crontab that supports it, spec.timeZone in Kubernetes, or the scheduler’s timezone setting.
The same schedule elsewhere
- crontab:
0 0 1 1 * /usr/local/bin/yearly.sh, or@yearly /usr/local/bin/yearly.sh. - GitHub Actions:
cron: '0 0 1 1 *'. GitHub doesn’t take@yearly, and in a public repository it disables scheduled workflows after 60 days without repository activity, long before the next run. - Kubernetes CronJob:
schedule: "@yearly", or"0 0 1 1 *". - AWS EventBridge:
cron(0 0 1 1 ? *). - systemd timer:
OnCalendar=yearly, which means*-01-01 00:00:00, withPersistent=true. - Spring
@Scheduled:0 0 0 1 1 *, or@yearly.