Skip to main content

Cron biweekly - every other week pattern

0 9 * * 1

At 09:00, only on Monday.

Next runs · UTC

Calendar

September 2026 · UTC

0 runs

About this tool

Cron has no native biweekly cadence. Schedule weekly and use a wrapper that checks the ISO week number to fire only on alternating weeks. The pattern below works on any cron-compatible scheduler.

The cron expression for biweekly (every other Monday at 09:00)

0 9 * * 1

Cron has no native “every other week” - the day-of-week field repeats weekly. The cron still fires weekly. A wrapper must skip alternate runs; persist the last successful run for an exact 14-day cadence. The expression above runs every Monday; the wrapper script exits on odd ISO weeks.

See the dedicated guide for the full breakdown: Cron every week.

Paste it into the editor above to see the next runs on a calendar.

When to run a job biweekly (every other Monday at 09:00)

  • Reports, invoices, or digests that go out every other week, where a wrapper script decides which weekly run does the work.
  • The cron still fires weekly. A wrapper must skip alternate runs; for an exact 14-day interval, trigger at least daily in UTC and persist the next UTC due timestamp.
  • Sprint or pay-period rituals that must land on the same weekday each time.

Run this cron anywhere

0 9 * * 1 is five-field cron syntax. It works as is in:

AWS EventBridge and Quartz use six-field expressions with a ? in one of the day fields, so convert first:

  • AWS EventBridge - cron(minute hour day-of-month month ? year); see the AWS guide.
  • Quartz Scheduler - prepend a seconds field (0) and replace one day field with ?; see the Quartz guide.

Useful variations

  • 0 9 * * 1 - weekly Monday 09:00 - the cron still fires weekly; a Bash wrapper gates it with `week=$(date +%V); ((10#$week % 2 == 0)) || exit 0`
  • 0 9 1,15 * * - approximately biweekly: every 1st and 15th of the month at 09:00
  • 0 9 * * 1,4 - twice a week (Mon and Thu) - see the twice-a-week guide

Gotchas when running biweekly (every other Monday at 09:00)

  • Not a 14-day cadence on its own - The cron still fires weekly. A wrapper must skip alternate runs; for an exact 14-day interval, trigger at least daily in UTC and persist the next UTC due timestamp. Use week=$(date +%V); ((10#$week % 2 == 0)) || exit 0 inside a Bash script, not on the crontab line, where % becomes a newline; ISO week 53 makes an even/odd rule fire on consecutive Mondays or skip three weeks.
  • Timezone and daylight saving - DST handling is scheduler-specific: Vixie/cronie can skip or double local matches; GitHub advances nonexistent local times; EventBridge Scheduler skips spring and runs once in the fall overlap. UTC-only Vercel and Cloudflare schedules are unaffected.
  • Missed runs are not replayed - If the host or platform is unavailable at the scheduled minute, standard cron simply waits for the next match. Add a heartbeat or alert if a skipped run must be noticed.
  • Day-of-week and day-of-month are OR-ed - In Vixie-style cron, restricting both fields runs the job when either matches. Keep day-of-month as * when the weekday is the only restriction you want.
  • Sunday numbering varies by dialect - Vixie-style cron accepts 0 and 7 as Sunday. AWS EventBridge and Quartz use 1 for Sunday and 7 for Saturday; prefer weekday names when translating dialects.

Examples

  • 0 18 * * *
    Every day at 18:00
  • 0 */5 * * *
    Every 5 hours
  • 0 18 * * 1-5
    Weekdays at 18:00
  • 0 0 1 * *
    Once a month, on the 1st at midnight

Cheatsheet

Full cheatsheet
FieldReq.RangeWildcards
minuteyes0-59, - * /
houryes0-23, - * /
day of monthyes1-31, - * /
monthyes1-12 or JAN-DEC, - * /
day of weekyes0-6 or names; some dialects use 0-7 or 1-7 — see Dialects, - * /

Frequently asked questions

Timing

How can a wrapper preserve an exact 14-day interval?

Trigger at least daily in UTC and run when the persisted UTC due timestamp has passed; after success, advance it by 1,209,600 seconds. A weekly local-time trigger cannot guarantee the exact interval because spring DST can make the check skip until the following week.

When does 0 9 * * 1 run for a biweekly job?

The cron trigger still fires weekly, every Monday at 09:00, not every other Monday. The wrapper makes alternate invocations exit without doing the work. Expression: 0 9 * * 1

Open in editor

Days and months

How can an ISO week wrapper run every other Monday?

Gate the weekly trigger with week=$(date +%V); ((10#$week % 2 == 0)) || exit 0. ISO week 53 can create consecutive selected Mondays or a three-week gap, so a parity wrapper is unsuitable when the interval must always be exactly 14 days.

Timezones and DST

Does daylight saving affect a biweekly Monday schedule?

Yes. A 09:00 local-time schedule stays at 09:00, but the elapsed gap across a DST change is 335 or 337 hours instead of 336. Use UTC when exact elapsed timing matters.

Timezone and DST reference

Platforms

What is the AWS EventBridge trigger for the biweekly wrapper?

Use cron(0 9 ? * MON *) in EventBridge, then apply the alternating-week check in the target. EventBridge has no native biweekly operator. Expression: 0 9 ? * MON *

Open in editor
AWS cron guide
What is the Quartz trigger for the biweekly wrapper?

Use 0 0 9 ? * MON to trigger every Monday at 09:00, then gate alternate weeks in the job. Quartz adds seconds first and still cannot represent an exact every-other-week interval. Expression: 0 0 9 ? * MON

Open in editor
Quartz cron guide
Can GitHub Actions run this biweekly pattern?

Yes, but schedule the workflow weekly and skip alternate runs in a step. GitHub Actions uses UTC by default, supports an optional IANA timezone, and its five-minute minimum does not restrict a weekly trigger.

Cron dialect matrix
Can Vercel Hobby run the weekly trigger for a biweekly job?

Yes. Vercel Hobby permits schedules no more frequent than once per day, so a weekly trigger is allowed; Vercel cron uses UTC, and the endpoint must perform the alternating-week check.

Vercel cron guide

Debugging

Where should a deployed biweekly wrapper store its state?

Store the next UTC due timestamp in durable, shared storage such as the job database. A local file is safe only on one persistent host; ephemeral or horizontally scaled workers can lose it or race.

How should retries and locking work for a biweekly wrapper?

Lock before reading the UTC due timestamp, and advance it only after successful work. This prevents concurrent daily checks from both running and keeps a failed attempt eligible for retry.

Crontap

Can Crontap run the biweekly wrapper with retries?

Yes. You can run the weekly HTTP trigger on Crontap with retries, while the endpoint keeps the ISO-week or persisted-timestamp gate that cron itself cannot express.

Schedule API calls

General

What is the cron expression for biweekly (every other Monday at 09:00)?

0 9 * * 1, plus a wrapper. The cron still fires weekly. A wrapper must skip alternate runs; for an exact 14-day interval, trigger at least daily in UTC and persist the next UTC due timestamp. Paste the expression into Linux crontab, Vercel cron, node-cron, or robfig/cron; AWS EventBridge and Quartz need the six-field form.

How can I verify this cron actually runs biweekly (every other Monday at 09:00)?

The editor above shows the next 30+ runs on a calendar in your local timezone, plus a plain-English description. If the calendar matches your intent, the cron is correct.

Does 0 9 * * 1 work on every platform?

Linux crontab, Vercel cron jobs, node-cron, robfig/cron, and Kubernetes CronJob accept the five-field form as is. AWS EventBridge and Quartz use six-field expressions with a ? in one of the day fields; see the AWS and Quartz guides for the conversion. Vercel's free Hobby plan caps the minimum frequency at once-per-day; the Pro plan removes that cap.

What happens if the previous run is still going when the next one fires?

Most schedulers will start the new run anyway, leading to overlap. To prevent this, wrap the command with flock -n /tmp/myjob.lock /path/to/script.sh on Linux, or set concurrencyPolicy: Forbid on Kubernetes CronJob. Vercel and EventBridge may overlap runs if the previous one is still executing; make the handler idempotent.

Write the cron here. Run it on Crontap.

Point Crontap at any URL. Pick any cron. Done.

WordPress, Shopify, Railway, Cloud Run, Vercel, HubSpot, Ghost, your own box. If it answers HTTP, Crontap can drive it on a clock you can read, in the timezone that actually matters, and page you when something breaks.

1.9k+ teams · Free forever tier · No credit card