Run Every Two Hours on Weekdays | CronBase
0 */2 * * 1-5 Every two hours on weekdays from Monday through Friday.
This cron expression schedules a task to run at the start of every second hour, specifically on the hour mark, from Monday through Friday. It does not execute on weekends, making it ideal for processing business-day data streams, synchronizing enterprise systems, and performing regular weekday maintenance tasks.
- Minute
- 0
- Hour
- */2
- Day of Month
- *
- Month
- *
- Day of Week
- 1-5
Next 5 Runs
- in 1d 3h
- in 1d 5h
- in 1d 7h
- in 1d 9h
- in 1d 11h
* Tools
Code & Implementations
#!/bin/bash
# Lock file to prevent overlapping executions
LOCKFILE="/var/run/weekday_sync.lock"
exec 200>"$LOCKFILE"
if ! flock -n 200; then
echo "Error: Another instance of the job is already running." >&2
exit 1
fi
echo "Starting weekday sync task..."
# Real-world task execution
curl -f -s https://api.example.com/sync || { echo "Sync failed" >&2; exit 1; }
echo "Task completed successfully." › Setup notes
Save this script to /usr/local/bin/weekday-sync.sh, make it executable with chmod +x, and add it to your system crontab using 'crontab -e'.
const cron = require('node-cron');
const axios = require('axios');
// Schedule task for every 2 hours on weekdays
cron.schedule('0 */2 * * 1-5', async () => {
console.log('Starting scheduled weekday data synchronization...');
try {
const response = await axios.post('https://api.example.com/v1/sync');
console.log(`Sync completed with status: ${response.status}`);
} catch (error) {
console.error('Execution failed during weekday sync:', error.message);
}
}, {
scheduled: true,
timezone: "UTC"
}); › Setup notes
Install node-cron and axios using npm, then run this script using node in a daemonized process manager like PM2 to ensure continuous execution.
import logging
from apscheduler.schedulers.blocking import BlockingScheduler
import requests
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('weekday_cron')
def execute_sync_job():
logger.info("Executing scheduled weekday synchronization job...")
try:
response = requests.post("https://api.example.com/jobs/sync", timeout=30)
response.raise_for_status()
logger.info(f"Job completed successfully: {response.status_code}")
except Exception as err:
logger.error(f"Job failed during execution: {err}")
if __name__ == '__main__':
scheduler = BlockingScheduler()
# 0 */2 * * 1-5 maps to day_of_week='mon-fri', hour='*/2', minute=0
scheduler.add_job(execute_sync_job, 'cron', day_of_week='mon-fri', hour='*/2', minute=0, timezone='UTC')
try:
scheduler.start()
except (KeyboardInterrupt, SystemExit):
pass › Setup notes
Install apscheduler and requests via pip. Run this script in a virtual environment as a background systemd service.
package main
import (
"log"
"net/http"
"time"
"github.com/robfig/cron/v3"
)
func main() {
// Use UTC timezone to avoid DST transition complications
c := cron.New(cron.WithLocation(time.UTC))
_, err := c.AddFunc("0 */2 * * 1-5", func() {
log.Println("Starting weekday pipeline execution...")
client := &http.Client{Timeout: 10 * time.Second}
resp, err := client.Post("https://api.example.com/pipeline", "application/json", nil)
if err != nil {
log.Printf("Pipeline execution failed: %v", err)
return
}
defer resp.Body.Close()
log.Printf("Pipeline execution completed with status: %s", resp.Status)
})
if err != nil {
log.Fatalf("Failed to schedule cron job: %v", err)
}
c.Start()
select {} // Block forever
} › Setup notes
Initialize a Go module, get the robfig/cron library, compile the binary, and run it as a supervisor-managed service.
package com.example.cron;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class WeekdaySyncScheduler {
private static final Logger logger = LoggerFactory.getLogger(WeekdaySyncScheduler.class);
private final RestTemplate restTemplate = new RestTemplate();
// Standard Spring cron format: second, minute, hour, day of month, month, day(s) of week
@Scheduled(cron = "0 0 */2 * * MON-FRI", zone = "UTC")
public void runWeekdayTask() {
logger.info("Starting weekday task execution...");
try {
String url = "https://api.example.com/tasks/trigger";
String response = restTemplate.postForObject(url, null, String.class);
logger.info("Task completed successfully: {}", response);
} catch (Exception e) {
logger.error("Error occurred while running weekday task", e);
}
}
} › Setup notes
Ensure @EnableScheduling is declared on your main Spring Boot application class. This component will automatically be scanned and executed.
apiVersion: batch/v1
kind: CronJob
metadata:
name: weekday-sync-job
namespace: default
spec:
schedule: "0 */2 * * 1-5"
concurrencyPolicy: Forbid
startingDeadlineSeconds: 600
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: sync-worker
image: curlimages/curl:latest
command:
- /bin/sh
- -c
- "curl -f -s https://api.example.com/sync || exit 1"
restartPolicy: OnFailure › Setup notes
Apply this manifest using 'kubectl apply -f cronjob.yaml'. The 'Forbid' concurrency policy ensures that if a job hangs, a new one will not start.
Last verified:
Monitor this schedule in production
Get alerted the moment this cron job fails, is late, or doesn't run. BetterStack tracks execution, duration, and output — no infrastructure required.
Platform Equivalents
AWS EventBridge
Standard cron expressions often need conversion for AWS EventBridge schedules.
cron(0 */2 ? * 1-5 *) Systemd Timer
OnCalendarMon..Fri *-*-* 00/2:00:00
[Unit]
Description=Timer for cron expression: 0 */2 * * 1-5
[Timer]
OnCalendar=Mon..Fri *-*-* 00/2:00:00
Persistent=true
[Install]
WantedBy=timers.target
Last verified:
Frequently Asked Questions
How does this schedule handle Daylight Saving Time (DST) transitions?
Standard cron relies on system time. During DST changes, the 2:00 AM run might execute twice or be skipped entirely. To prevent issues, configure your servers to run on UTC or use an application-level scheduler that handles DST offsets seamlessly.
What happens if a job takes longer than two hours to complete?
If a job exceeds the two-hour window, standard cron will start a new instance alongside the running one. This can cause race conditions or resource exhaustion. Use a locking mechanism like flock in Bash or distributed locks in your application code to prevent overlapping runs.
Does this expression run on weekends at all?
No, the day-of-week field is restricted to 1-5 (Monday through Friday). The schedule stops running after the last execution on Friday (usually 10 PM depending on alignment) and resumes on Monday at midnight (00:00).
How can I test this cron schedule locally before deploying to production?
You can use online parsers to verify the execution times or simulate the schedule using a tool like croniter in Python or robfig/cron dry-runs in Go. Additionally, check your local system logs after running a short-interval test.
Why is my task running at odd hours instead of even hours?
The step syntax */2 starts counting from 0. Therefore, executions occur at 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, and 22 hours. If your system clock is misconfigured or set to a different timezone, these hours might not align with your local business day.
* Explore
Related expressions you might need
Last verified: