Schedule Daily Maintenance Tasks at 2:00 AM | CronBase
0 2 * * * Every day at two o'clock in the morning.
This cron expression executes a scheduled task every single day at exactly two o'clock in the morning. It is widely used by system administrators and software engineers to run resource-intensive operations, such as database backups, system updates, and log rotations, during off-peak hours to minimize performance impact on active users.
- Minute
- 0
- Hour
- 2
- Day of Month
- *
- Month
- *
- Day of Week
- *
Next 5 Runs
- in 5h 23m
- in 1d 5h
- in 2d 5h
- in 3d 5h
- in 4d 5h
* Tools
Code & Implementations
#!/usr/bin/env bash
# Daily backup script executed at 2:00 AM
set -euo pipefail
BACKUP_DIR="/var/backups/db"
LOG_FILE="/var/log/backup.log"
mkdir -p "$BACKUP_DIR"
echo "[$(date -u)] Starting daily backup..." >> "$LOG_FILE"
if pg_dump -U postgres prod_db > "$BACKUP_DIR/db_$(date +%F).sql"; then
echo "[$(date -u)] Backup completed successfully." >> "$LOG_FILE"
else
echo "[$(date -u)] Error: Backup failed!" >&2
exit 1
fi › Setup notes
Add this script to your crontab by running crontab -e and appending: 0 2 * * * /usr/local/bin/backup.sh >> /var/log/cron_backup.log 2>&1.
const cron = require('node-cron');
const { exec } = require('child_process');
// Schedule task to run at 2:00 AM daily in UTC
cron.schedule('0 2 * * *', () => {
console.log(`[${new Date().toISOString()}] Initiating daily system cleanup...`);
exec('npm prune && npm cache clean --force', (error, stdout, stderr) => {
if (error) {
console.error(`Cleanup error: ${error.message}`);
return;
}
if (stderr) {
console.warn(`Cleanup warning: ${stderr}`);
}
console.log(`Cleanup success: ${stdout}`);
});
}, {
scheduled: true,
timezone: "UTC"
}); › Setup notes
Install node-cron via npm. This script schedules a daily cleanup job at 2:00 AM UTC, handling process execution safely.
import logging
from datetime import datetime
from apscheduler.schedulers.blocking import BlockingScheduler
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def daily_data_sync():
logging.info("Starting daily data synchronization job...")
try:
# Simulated data sync logic
logging.info("Data synchronization completed successfully.")
except Exception as e:
logging.error(f"Synchronization failed: {str(e)}")
if __name__ == "__main__":
scheduler = BlockingScheduler()
# Schedule job for 2:00 AM daily in UTC timezone
scheduler.add_job(daily_data_sync, 'cron', hour=2, minute=0, timezone='UTC')
logging.info("Scheduler initialized. Waiting for 2:00 AM daily execution...")
try:
scheduler.start()
except (KeyboardInterrupt, SystemExit):
logging.info("Scheduler stopped manually.") › Setup notes
Install apscheduler via pip. This script executes the daily sync function at 2:00 AM UTC with structured logging and error handling.
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)
// Initialize cron with UTC timezone explicitly
c := cron.New(cron.WithLocation(time.UTC))
_, err := c.AddFunc("0 2 * * *", func() {
logger.Println("Daily maintenance routine started...")
// Place backup or cleanup logic here
logger.Println("Daily maintenance routine finished successfully.")
})
if err != nil {
logger.Fatalf("Failed to schedule cron job: %v", err)
}
c.Start()
logger.Println("Cron scheduler started for 2:00 AM UTC daily execution.")
// Graceful shutdown handling
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<-sigChan
logger.Println("Shutting down scheduler...")
c.Stop()
} › Setup notes
Import github.com/robfig/cron/v3 to schedule the job. The scheduler runs explicitly in UTC and includes graceful shutdown handling.
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 DailyMaintenanceTask {
private static final Logger logger = LoggerFactory.getLogger(DailyMaintenanceTask.class);
// Runs at 2:00 AM daily using the server's timezone (or UTC if configured)
@Scheduled(cron = "0 2 * * *", zone = "UTC")
public void executeDailyCleanup() {
logger.info("Daily maintenance task initiated.");
try {
// Perform database pruning or system cleanup
logger.info("Daily maintenance task completed successfully.");
} catch (Exception e) {
logger.error("Error occurred during daily maintenance: ", e);
}
}
} › Setup notes
Enable scheduling in your Spring Boot application by adding @EnableScheduling to your main class, then apply this component.
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-db-backup
namespace: production
spec:
schedule: "0 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
jobTemplate:
spec:
template:
spec:
containers:
- name: backup-runner
image: postgres:15-alpine
command:
- /bin/sh
- -c
- "pg_dump -h db-service -U postgres prod_db > /mnt/backups/db_$(date +%F).sql"
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- name: backup-storage
mountPath: /mnt/backups
restartPolicy: OnFailure
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: backup-pvc › Setup notes
Apply this manifest with kubectl apply -f cronjob.yaml. It schedules a daily container run at 2:00 AM, using standard concurrency limits.
Last verified:
Keep this cron job monitored 24/7
UptimeRobot alerts you the moment a scheduled job stops responding. Free plan monitors up to 50 endpoints — no credit card required.
Platform Equivalents
AWS EventBridge
Standard cron expressions often need conversion for AWS EventBridge schedules.
cron(0 2 * * ? *) Systemd Timer
OnCalendar*-*-* 02:00:00
[Unit]
Description=Timer for cron expression: 0 2 * * *
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
Last verified:
Frequently Asked Questions
How does Daylight Saving Time affect a cron job scheduled at 2:00 AM?
In local time zones, spring-forward transitions skip the 2:00 AM hour, causing the job to be missed. In autumn fall-back transitions, the 2:00 AM hour occurs twice, which might trigger the job twice. To prevent this, configure your servers and schedulers to use Coordinated Universal Time (UTC).
What is the best way to handle overlapping runs if the 2:00 AM job takes over 24 hours?
Use a locking mechanism like flock in Bash, a distributed lock manager like Redis (Redlock) in multi-node environments, or configure 'concurrencyPolicy: Forbid' in Kubernetes CronJobs to prevent a new instance from starting before the previous one completes.
How can I stagger multiple jobs that are all scheduled for 2:00 AM?
Avoid scheduling everything at exactly 2:00 AM to prevent resource spikes. You can stagger schedules (e.g., 2:00, 2:15, 2:30), add a randomized sleep delay (jitter) at the beginning of your scripts, or use a message-queue-driven system to process jobs sequentially.
Can I run this schedule on a specific day of the week or month instead of daily?
Yes. To run only on Sundays at 2:00 AM, use '0 2 * * 0'. To run only on the first day of every month at 2:00 AM, use '0 2 1 * *'. Modifying the fourth and fifth fields allows you to easily restrict the daily execution to specific dates.
How do I capture and monitor failures for a cron job running at 2:00 AM?
Redirect standard output and standard error to a log file or external log aggregator. Integrate alert triggers using tools like Prometheus, Sentry, or health check ping services (e.g., healthchecks.io) that alert you if the job fails to report completion within a specified window.
* Explore
Related expressions you might need
Last verified: