No cron expression runs every other week: cron fields describe minutes, hours, days of the month, months and weekdays, and nothing counts weeks. The setups that hold up are a weekly schedule such as 0 9 * * 1 with a check that skips alternate weeks, or settling for two fixed dates a month. */14 in the day-of-month field looks right but drifts.
Why */14 doesn't work
0 9 */14 * * matches the 1st, 15th and 29th of each month, because the step starts again every month. From November 2026 it runs on November 15, November 29, December 1 and December 15: 14 days apart, then 2.
0 9 * * 1/2 isn't it either. In the day-of-week field 1/2 means every second weekday from Monday, so Monday, Wednesday, Friday and Sunday, every week.
Option 1: weekly schedule, skip odd weeks in your endpoint
Schedule the URL every Monday at 09:00 (0 9 * * 1) and return early on alternate weeks. Count whole weeks since a fixed Monday rather than using the ISO week number: some years have 53 ISO weeks, which puts two odd weeks back to back.
// Runs every Monday; does the work every other Monday.
const ANCHOR = Date.UTC(2026, 10, 2); // Monday, November 2, 2026: a week that should run
const WEEK = 7 * 24 * 60 * 60 * 1000;
const weeks = Math.floor((Date.now() - ANCHOR) / WEEK);
if (weeks % 2 !== 0) return Response.json({ skipped: 'off week' });
// ... biweekly workThe off-week calls still show in the RunLater log with the skipped response, so you can see the schedule is alive. Each one counts as a run: a weekly request uses 4 or 5 runs a month.
Option 2: the same check in a crontab
# every other Monday at 09:00 (even weeks since 1970-01-01)
0 9 * * 1 [ $(( $(date +\%s) / 604800 \% 2 )) -eq 0 ] && /usr/local/bin/biweekly.sh604800 is the number of seconds in a week. Change -eq 0 to -eq 1 to run on the other set of Mondays. Both % signs need a backslash in a crontab line.
Option 3: twice a month instead
If the job only needs to run about every two weeks, fixed dates are simpler: 0 9 1,15 * * runs on the 1st and 15th. For the first and third Monday, create two requests, 0 9 * * 1#1 and 0 9 * * 1#3 (see nth weekday schedules).
Every two weeks with a one-off start date
If the cycle starts on a specific date (a sprint, a payroll period), put that Monday in ANCHOR. The check keeps the rhythm across month and year boundaries because it counts weeks rather than calendar fields.
Related: every Monday at 9am and the cron expression guide.
Frequently asked questions
Is there a cron expression for every other week?
No. Cron fields describe minutes, hours, days of the month, months and weekdays, but nothing counts weeks. Run the job weekly and skip alternate weeks in the job, or use two fixed dates a month.
Does 0 9 * * 1/2 mean every other Monday?
No. In the day-of-week field 1/2 means every second weekday starting from Monday: Monday, Wednesday, Friday and Sunday, every week.
Why does */14 in the day-of-month field drift?
The step restarts every month. */14 matches the 1st, 15th and 29th, so the gap is 14 days inside a month and 1 to 3 days across the month boundary.
Why count weeks from a fixed date instead of using the ISO week number?
Some years have 53 ISO weeks, so week 53 and week 1 of the next year are both odd and the job runs two weeks in a row. Whole weeks since a fixed Monday never break the alternation.