crontool
Paste a schedule, read it in English, see the next runs.

Cron Expression: Every 2 Weeks (Biweekly)

Cron counts days and months, not weeks, so there is no single line for “every 2 weeks.” The reliable pattern is to run weekly and skip on alternate weeks using the ISO week number. Here is the exact gate.

Why cron can't do biweekly alone

The day-of-month field resets every month and the day-of-week field has no “every other week” notion, so no combination of fields gives a stable 14-day cycle across month and year boundaries.

The common wrong answer

0 9 */14 * * looks biweekly but */14 on day-of-month fires on the 1st, 15th, and 29th, then resets — so runs land on the 29th and then the 1st, only three days apart. It is not a true 14-day cycle.

The correct pattern

Run every Monday at 9:00 and gate on the ISO week number being even (or odd):

0 9 * * 1 in cron, then: [ $(( $(date +%V | sed 's/^0//') % 2 )) -eq 0 ] || exit 0. %V is the ISO week (01–53); keeping even weeks gives a clean every-other-Monday schedule. Swap -eq 0 for -eq 1 to shift the phase.

Caveat at year end

A year with 53 ISO weeks means two odd weeks meet at the boundary, causing one 7-day gap instead of 14 once every few years. For most reporting jobs that is acceptable; if not, track the last run in a timestamp file and require 14 days elapsed.

FAQ

Is there a cron expression for every 2 weeks?

Not in one line — cron has no week counter. Run weekly (0 9 * * 1) and gate the script on the ISO week number modulo 2.

Why is 0 9 */14 * * wrong for biweekly?

*/14 on day-of-month fires on the 1st, 15th, and 29th, then resets each month, so the 29th and the next 1st are only days apart — not a true 14-day cycle.

How do I keep exact 14-day spacing?

Store the last run time in a file and require that 14 days have elapsed before the script proceeds; this survives 53-week years.