Run Weekly Jobs on Wednesday at 9 AM | CronBase
0 9 * * 3 Every Wednesday morning at nine o'clock
The `0 9 * * 3` cron expression schedules a job to execute every Wednesday at exactly 9:00 AM. This mid-week, mid-morning cadence is highly effective for running non-disruptive weekly maintenance, generating business intelligence reports, sync operations, and kicking off mid-week marketing campaigns during active business hours.
- Minute
- 0
- Hour
- 9
- Day of Month
- *
- Month
- *
- Day of Week
- 3
Next 5 Runs
- in 3d 12h
- in 10d 12h
- in 17d 12h
- in 24d 12h
- in 31d 12h
* Tools
Code & Implementations
#!/usr/bin/env bash
# Add this to your crontab using 'crontab -e'
# 0 9 * * 3 /usr/local/bin/wednesday_cleanup.sh >> /var/log/cron_wednesday.log 2>&1
set -euo pipefail
LOG_FILE="/var/log/cron_wednesday.log"
echo "[$(date -u '+\%Y-\%m-\%dT\%H:\%M:\%SZ')] Starting weekly Wednesday maintenance task..." >> "$LOG_FILE"
# Run the actual maintenance payload
if /usr/local/bin/perform_maintenance; then
echo "[$(date -u '+\%Y-\%m-\%dT\%H:\%M:\%SZ')] Maintenance completed successfully." >> "$LOG_FILE"
else
echo "[$(date -u '+\%Y-\%m-\%dT\%H:\%M:\%SZ')] ERROR: Maintenance task failed!" >> "$LOG_FILE"
# Trigger alert payload here (e.g., Slack webhook or PagerDuty)
exit 1
fi › Setup notes
Add the cron line to your user's crontab using crontab -e. The wrapper script ensures proper logging, error handling, and exit codes.
const cron = require('node-cron');
const logger = require('./logger'); // Assume a production logger like Winston
// Schedule task to run every Wednesday at 9:00 AM
const task = cron.schedule('0 9 * * 3', async () => {
logger.info('Starting weekly Wednesday report generation pipeline...');
try {
await runWeeklyReportPipeline();
logger.info('Weekly Wednesday report generation completed successfully.');
} catch (error) {
logger.error('Failed to execute weekly Wednesday report pipeline', { error: error.message, stack: error.stack });
// Handle alerting logic here
}
}, {
scheduled: true,
timezone: "America/New_York" // Explicitly lock timezone to avoid DST drift issues
});
task.start(); › Setup notes
Install the node-cron package. It is recommended to define an explicit timezone in the configuration options to prevent unexpected execution times during daylight saving changes.
import logging
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s')
logger = logging.getLogger(__name__)
def execute_midweek_sync():
logger.info("Starting mid-week synchronization process...")
try:
# Your production business logic here
pass
logger.info("Mid-week synchronization completed successfully.")
except Exception as e:
logger.error(f"Sync process encountered an unhandled exception: {str(e)}", exc_info=True)
# Trigger alerting system
if __name__ == "__main__":
scheduler = BlockingScheduler()
# standard cron pattern: minute=0, hour=9, day_of_week=2 (0 is Monday, 2 is Wednesday in APScheduler)
trigger = CronTrigger(day_of_week='wed', hour=9, minute=0, timezone='UTC')
scheduler.add_job(execute_midweek_sync, trigger=trigger, id='wednesday_9am_sync')
logger.info("Starting scheduler daemon...")
try:
scheduler.start()
except (KeyboardInterrupt, SystemExit):
logger.info("Scheduler stopped cleanly.") › Setup notes
Install apscheduler via pip. This script utilizes the BlockingScheduler and configures a CronTrigger explicitly mapped to Wednesday at 9:00 AM UTC.
package main
import (
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/robfig/cron/v3"
)
func main() {
logger := log.New(os.Stdout, "CRON: ", log.LstdFlags|log.Lshortfile)
// Use the v3 cron package with support for standard 5-field cron spec
loc, err := time.LoadLocation("UTC")
if err != nil {
logger.Fatalf("Failed to load UTC timezone: %v", err)
}
c := cron.New(cron.WithLocation(loc))
_, err = c.AddFunc("0 9 * * 3", func() {
logger.Println("Executing Wednesday 9:00 AM batch task...")
err := performBatchProcessing()
if err != nil {
logger.Printf("ERROR: Batch processing failed: %v", err)
// Implement telemetry/alerting call here
} else {
logger.Println("Batch task completed successfully.")
}
})
if err != nil {
logger.Fatalf("Failed to schedule job: %v", err)
}
c.Start()
logger.Println("Scheduler started. Press Ctrl+C to exit.")
// Keep application running until interrupted
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<-sigChan
logger.Println("Stopping cron scheduler...")
c.Stop()
}
func performBatchProcessing() error {
// Production logic goes here
return nil
} › Setup notes
Initialize your project with github.com/robfig/cron/v3. This production-ready setup handles graceful shutdown signals and explicitly locks the scheduler to UTC.
package com.example.cron;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class WednesdayCronJob {
private static final Logger logger = LoggerFactory.getLogger(WednesdayCronJob.class);
// Standard 6-field Spring cron syntax (seconds, minutes, hours, day of month, month, day of week)
// "0 0 9 * * WED" runs every Wednesday at 9:00 AM
@Scheduled(cron = "0 0 9 * * WED", zone = "UTC")
public void executeWednesdayTask() {
logger.info("Starting scheduled Wednesday 9:00 AM system diagnostic...");
try {
runDiagnosticSuite();
logger.info("System diagnostic completed successfully.");
} catch (Exception ex) {
logger.error("Exception occurred during Wednesday diagnostic task execution: ", ex);
// Trigger pager alarm notification
}
}
private void runDiagnosticSuite() {
// Production diagnostic logic here
}
} › Setup notes
Enable scheduling in your Spring Boot application by adding @EnableScheduling to your configuration class. The @Scheduled annotation uses a six-field cron expression where the first field is seconds.
apiVersion: batch/v1
kind: CronJob
metadata:
name: wednesday-reports-job
namespace: production
spec:
schedule: "0 9 * * 3"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
jobTemplate:
spec:
template:
spec:
containers:
- name: reporter
image: registry.example.com/analytics/reporter:v1.2.0
imagePullPolicy: IfNotPresent
env:
- name: NODE_ENV
value: "production"
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
restartPolicy: OnFailure › Setup notes
Deploy this manifest to your cluster. It includes a concurrencyPolicy: Forbid setting which is critical to prevent overlapping runs if a previous Wednesday execution hangs.
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 9 ? * 3 *) Systemd Timer
OnCalendarWed *-*-* 09:00:00
[Unit]
Description=Timer for cron expression: 0 9 * * 3
[Timer]
OnCalendar=Wed *-*-* 09:00:00
Persistent=true
[Install]
WantedBy=timers.target
Last verified:
Frequently Asked Questions
How does daylight saving time affect this Wednesday 9 AM schedule?
If your system timezone is set to a local zone that observes DST, the job will shift relative to UTC but remain at 9:00 AM local time. To maintain a strict UTC interval, run your cron daemon in UTC, which means the local execution time will shift by one hour twice a year.
What happens if the server is offline at Wednesday 9:00 AM?
Standard cron does not catch up on missed executions. If your server is offline during the trigger window, the job will not run until the following Wednesday. For critical tasks, use an orchestrator with a misfire instruction or 'anacron' for local environments.
How can I prevent this weekly job from overlapping with itself if it runs long?
Since this job runs once a week, an overlap is highly unlikely unless the job hangs. Implement file-based locking using 'flock' in Bash, use a distributed lock manager like Redis for microservices, or set 'concurrencyPolicy: Forbid' in Kubernetes.
Can I run this job on multiple specific days instead of just Wednesday?
Yes, you can modify the fifth field. For example, changing the expression to `0 9 * * 1,3,5` will run the job at 9:00 AM on Mondays, Wednesdays, and Fridays instead of only on Wednesdays.
How do I monitor and alert on failures for this weekly cron job?
Because weekly jobs run infrequently, silent failures are dangerous. Integrate a push-monitoring tool (like Healthchecks.io or Opsgenie) that expects a ping every Wednesday morning, and configure it to alert your team if the ping is missed.
* Explore
Related expressions you might need
Last verified: