Run Twice Daily Jobs at Midnight and Noon | CronBase
0 0,12 * * * Every day at midnight and noon
The `0 0,12 * * *` cron expression schedules a task to run twice every day, specifically at midnight and at noon. This twelve-hour interval is ideal for executing semi-daily tasks such as database synchronization, batch processing, log rotations, and system health reports without overloading your servers during peak operational business hours.
- Minute
- 0
- Hour
- 0,12
- Day of Month
- *
- Month
- *
- Day of Week
- *
Next 5 Runs
- in 3h 18m
- in 15h 18m
- in 1d 3h
- in 1d 15h
- in 2d 3h
* Tools
Code & Implementations
#!/usr/bin/env bash
# Production-ready cron execution wrapper with locking and logging
set -euo pipefail
LOCKFILE="/var/lock/twice_daily_job.lock"
LOGFILE="/var/log/twice_daily_job.log"
exec 9>"$LOCKFILE"
if ! flock -n 9; then
echo "[$(date -u)] Execution skipped: Lock already held by another process." >> "$LOGFILE"
exit 1
fi
echo "[$(date -u)] Starting twice-daily maintenance task..." >> "$LOGFILE"
if /usr/local/bin/run-backup; then
echo "[$(date -u)] Task completed successfully." >> "$LOGFILE"
else
echo "[$(date -u)] ERROR: Task failed." >> "$LOGFILE" >&2
exit 2
fi › Setup notes
Save this script to /usr/local/bin/twice-daily.sh, make it executable with chmod +x, and register it in your system crontab using: 0 0,12 * * * /usr/local/bin/twice-daily.sh
const cron = require('node-cron');
const { exec } = require('child_process');
// Schedule task to run twice daily at midnight and noon
cron.schedule('0 0,12 * * *', () => {
console.log(`[${new Date().toISOString()}] Initiating twice-daily synchronization...`);
exec('/usr/local/bin/sync-data.sh', (error, stdout, stderr) => {
if (error) {
console.error(`[ERROR] Job failed: ${error.message}`);
return;
}
if (stderr) {
console.warn(`[WARN] Standard error output: ${stderr}`);
}
console.log(`[SUCCESS] Output: ${stdout}`);
});
}, {
scheduled: true,
timezone: "UTC"
}); › Setup notes
Install node-cron using npm install node-cron, then run this script using Node.js in a long-running process manager like PM2.
import logging
from datetime import datetime
from apscheduler.schedulers.blocking import BlockingScheduler
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s] %(message)s')
logger = logging.getLogger(__name__)
def execute_twice_daily_job():
logger.info("Starting twice-daily data pipeline execution...")
try:
# Business logic here
logger.info("Pipeline execution finished successfully.")
except Exception as e:
logger.error(f"Execution failed with error: {str(e)}", exc_info=True)
if __name__ == "__main__":
scheduler = BlockingScheduler(timezone="UTC")
# 0 0,12 * * * translation: minute=0, hour=0,12
scheduler.add_job(execute_twice_daily_job, 'cron', hour='0,12', minute='0', id='twice_daily_sync')
logger.info("Scheduler initialized. Running twice daily at 00:00 and 12:00 UTC.")
try:
scheduler.start()
except (KeyboardInterrupt, SystemExit):
logger.info("Scheduler stopped cleanly.") › Setup notes
Install the APScheduler package using pip install apscheduler, then execute this Python script in a systemd service or container background daemon.
package main
import (
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/robfig/cron/v3"
)
func runTwiceDailyTask() {
log.Println("Starting scheduled twice-daily cleanup operation...")
defer func() {
if r := recover(); r != nil {
log.Printf("ERROR: Task panicked: %v", r)
}
}()
time.Sleep(5 * time.Second) // Simulate work
log.Println("Cleanup operation completed successfully.")
}
func main() {
c := cron.New(cron.WithLocation(time.UTC))
_, err := c.AddFunc("0 0,12 * * *", runTwiceDailyTask)
if err != nil {
log.Fatalf("Failed to schedule twice-daily job: %v", err)
}
c.Start()
log.Println("Cron scheduler started. Running twice daily at 00:00 and 12:00 UTC.")
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<-sigChan
log.Println("Shutting down scheduler gracefully...")
c.Stop()
} › Setup notes
Initialize a Go module, run go get github.com/robfig/cron/v3, and execute with go run main.go as a background service.
package com.cronbase.scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class TwiceDailyTaskScheduler {
private static final Logger logger = LoggerFactory.getLogger(TwiceDailyTaskScheduler.class);
// Spring cron uses 6 fields: second, minute, hour, day of month, month, day of week
@Scheduled(cron = "0 0 0,12 * * *", zone = "UTC")
public void executeTwiceDailyTask() {
logger.info("Initiating scheduled twice-daily maintenance process...");
try {
performMaintenance();
logger.info("Maintenance process completed successfully.");
} catch (Exception e) {
logger.error("Error occurred during scheduled maintenance execution", e);
}
}
private void performMaintenance() throws Exception {
// Actual business logic execution
}
} › Setup notes
Ensure @EnableScheduling is active in your Spring Boot application class, then register this Component in your application context.
apiVersion: batch/v1
kind: CronJob
metadata:
name: twice-daily-cleanup
namespace: production
spec:
schedule: "0 0,12 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
jobTemplate:
spec:
template:
spec:
containers:
- name: cleanup-worker
image: registry.example.com/ops/cleanup-tool:v1.2.0
imagePullPolicy: IfNotPresent
env:
- name: ENVIRONMENT
value: "production"
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "100m"
memory: "256Mi"
restartPolicy: OnFailure › Setup notes
Apply this manifest using kubectl apply -f cronjob.yaml, ensuring your cluster timezone is configured correctly or using K8s v1.21+ timezone fields.
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 0,12 * * ? *) Systemd Timer
OnCalendar*-*-* 00,12:00:00
[Unit]
Description=Timer for cron expression: 0 0,12 * * *
[Timer]
OnCalendar=*-*-* 00,12:00:00
Persistent=true
[Install]
WantedBy=timers.target
Last verified:
Frequently Asked Questions
How does this schedule handle Daylight Saving Time (DST) changes?
If your host system timezone is configured to a local zone that observes DST, this schedule will execute either twice, once, or at unexpected times during clock shifts. To avoid this, always configure your cron daemon or orchestrator to run in UTC.
What happens if the midnight execution runs longer than 12 hours?
If the task duration exceeds 12 hours, the noon execution will overlap. To prevent resource exhaustion, implement locking mechanisms (like flock in bash or Redis locks in distributed apps) and set the concurrency policy to 'Forbid' in Kubernetes.
Can I offset this execution to avoid peak traffic at exactly 12:00?
Yes. If noon is a high-traffic period for your application, you can shift the schedule by changing the minutes and hours (e.g., '30 1,13 * * *' to run at 01:30 and 13:30) to stagger resource consumption away from peak hours.
How should I monitor if one of the twice-daily runs fails?
Use a dead-man's switch or heartbeats (e.g., Healthchecks.io or Prometheus Pushgateway). If the service fails to ping the monitoring system within a 13-hour window, trigger an alert to your on-call team.
Is this schedule equivalent to running a job every 12 hours?
Yes, '0 0,12 * * *' is functionally identical to '0 */12 * * *'. Both expressions trigger at exactly 00:00 and 12:00. The explicit listing style ('0,12') is often preferred for readability over step intervals.
* Explore
Related expressions you might need
Last verified: