Cron Expression for Biweekly / Every Two Weeks
Table of Contents
Standard cron has no "every two weeks" option — there is no week field, and step notation doesn't apply to weeks. */2 in the day-of-week field means "every 2nd day of week" (which is nonsense), not "every 2 weeks." Use our free cron generator to build the closest approximation, then pick the right workaround below for your use case.
The distinction between "twice a month" and "true biweekly (every 14 days)" matters — they produce different schedules and require different approaches.
Why Standard Cron Has No "Every 2 Weeks" Option
Cron's five fields cover minutes, hours, day-of-month, month, and day-of-week. There is no week-of-year field and no week-number field. The step operator (/) only works within a field's own range — */2 in day-of-week means every 2nd value within 0-7, which is meaningless for biweekly scheduling.
This is a known limitation. The two separate problems developers are actually trying to solve:
- "Twice a month" (semi-monthly): Run on the 1st and 15th, or 1st and 16th. Not exactly 14 days apart but predictable calendar dates.
- "True biweekly" (every 14 days): Run exactly 14 days after the last run, regardless of month boundaries. Cron cannot do this natively.
Which one you need determines which workaround to use.
Workaround 1: Fixed Dates for Semi-Monthly Scheduling
If "approximately every two weeks" is acceptable and calendar dates matter more than exact 14-day intervals, use two specific days of the month:
0 9 1,15 * * # 9 AM on the 1st and 15th of every month
0 9 1,16 * * # 9 AM on the 1st and 16th (15-day gap first run, 15 days second)
0 0 1,15 * * # Midnight on the 1st and 15th
Build the exact dates you want in the cron generator using the comma-list option for day-of-month.
Gap behavior: The 1st to 15th is always 14 days. The 15th to the 1st is 14-17 days depending on the month. For most business use cases (payroll, newsletters, reports), this is acceptable. For exact 14-day intervals, it is not.
Sell Custom Apparel — We Handle Printing & Free ShippingWorkaround 2: Run Weekly, Check Week Number in Script
Schedule the job to run every week and add a week-number check inside the script. On Linux, date +%V gives the ISO week number (1-52):
# Crontab entry — runs every Monday at 9 AM
0 9 * * 1 /path/to/biweekly-check.sh
# biweekly-check.sh
#!/bin/bash
WEEK=$(date +%V)
if (( WEEK % 2 == 0 )); then
/path/to/actual-job.sh
fi
This gives you true alternating weeks — the job runs only on even-numbered ISO weeks (or odd, depending on your modulo condition). Adjust the start reference: if you want it to run this week, check which week number today falls on and choose == 0 or == 1 accordingly.
Limitation: Week 52 wraps to Week 1 at year-end, which can cause two consecutive runs or a skipped run depending on how week 53 (some years have one) falls. Add a date range guard for production use.
Workaround 3: systemd Timer for True 14-Day Intervals
On Linux systems with systemd, timers support a OnCalendar format that can express "every 14 days" properly:
# /etc/systemd/system/biweekly-job.timer
[Unit]
Description=Biweekly job
[Timer]
OnCalendar=*-*-01/14 09:00:00
Persistent=true
[Install]
WantedBy=timers.target
*-*-01/14 means "starting on the 1st of each month, every 14 days." This is a true 14-day step — systemd timers have week-level and day-interval arithmetic that cron lacks.
Activate with: systemctl enable --now biweekly-job.timer
Check next run with: systemctl list-timers biweekly-job.timer
Systemd timers also have Persistent=true which catches missed runs after downtime — unlike cron, which silently skips.
Biweekly Scheduling on Specific Platforms
| Platform | Native biweekly? | Best approach |
|---|---|---|
| Linux crontab | No | Fixed dates (1,15) or week-check script |
| GitHub Actions | No | Two date entries: 0 9 1,15 * * |
| Kubernetes CronJob | No | Fixed dates or wrapper Job with week logic |
| AWS EventBridge | No | cron(0 9 1,15 * ? *) |
| Spring Boot @Scheduled | No | Fixed dates or @Scheduled + @ConditionalOnExpression |
| systemd timers | Yes | OnCalendar=*-*-01/14 |
| Airflow | Partial | Use timedelta(weeks=2) for true interval, or fixed dates cron |
For most CI/CD platforms and cloud schedulers, fixed dates (1,15) is the pragmatic choice. For backend server jobs where true 14-day precision matters, migrate to systemd timers.
Try It Free — No Signup Required
Runs 100% in your browser. No account, no install, no limits.
Open Free Cron GeneratorFrequently Asked Questions
Is there a cron expression for "every 2 weeks"?
No — standard 5-field cron has no week-of-year field and no way to express "every 14 days" natively. The closest approximation is "0 9 1,15 * *" (twice a month on the 1st and 15th), which produces gaps of 14 days and 14-17 days alternating. For true 14-day intervals, use a systemd timer with "OnCalendar=*-*-01/14" or a weekly cron job with a script-level even/odd week check.
What does */2 in the day-of-week field mean?
It means "every 2nd value in the range 0-7" — which evaluates to Sunday (0), Tuesday (2), Thursday (4), Saturday (6). It does NOT mean "every 2 weeks." The slash operator is a step within the field's own range, not a multi-week interval. This is one of the most common cron misconceptions.
Can GitHub Actions schedule a workflow every two weeks?
Not natively. The closest option is "0 9 1,15 * *" which runs on the 1st and 15th of each month — close to biweekly but not exact 14-day intervals. Alternatively, use a manual workflow_dispatch trigger and run it biweekly by convention, or set up an external scheduler (AWS EventBridge, Zapier) to trigger your workflow via the GitHub API on a true 14-day interval.

