Run Daily Late-Night Maintenance at 11:45 PM | CronBase
45 23 * * * Every day late in the evening, exactly fifteen minutes before midnight.
The `45 23 * * *` cron expression schedules a task to run every day at exactly 11:45 PM. This late-night timing is ideal for executing end-of-day database backups, running daily log rotations, compiling daily activity reports, and performing system cleanup tasks right before the calendar day transitions to midnight.
- Minute
- 45
- Hour
- 23
- Day of Month
- *
- Month
- *
- Day of Week
- *
Next 5 Runs
- in 3h 7m
- in 1d 3h
- in 2d 3h
- in 3d 3h
- in 4d 3h
* Tools
Code & Implementations
#!/usr/bin/env bash
# Production-ready daily late-night backup script designed for 23:45 execution.
# Uses flock to prevent concurrent execution if a previous run hangs.
set -euo pipefail
LOCKFILE="/var/lock/daily_backup_2345.lock"
exec 9>"$LOCKFILE"
if ! flock -n 9; then
echo "Error: Another instance of the daily backup is already running." >&2
exit 1
fi
echo "[$(date -u)] Starting late-night daily database backup..."
# Simulate database backup
if pg_dump -U postgres prod_db > /backups/db_$(date +%F).sql; then
echo "[$(date -u)] Daily backup completed successfully."
else
echo "[$(date -u)] Daily backup failed!" >&2
exit 2
fi › Setup notes
Save this script to /usr/local/bin/daily-backup.sh, make it executable with chmod +x, and add '45 23 * * * /usr/local/bin/daily-backup.sh' to your system crontab.
const cron = require('node-cron');
const { exec } = require('child_process');
// Schedule the task to run every day at 23:45 (11:45 PM)
// Cron expression: 45 23 * * *
cron.schedule('45 23 * * *', () => {
console.log(`[${new Date().toISOString()}] Initiating scheduled late-night cleanup...`);
exec('/usr/local/bin/cleanup-logs.sh', (error, stdout, stderr) => {
if (error) {
console.error(`[ERROR] Cleanup failed: ${error.message}`);
return;
}
if (stderr) {
console.warn(`[WARN] Cleanup stderr: ${stderr}`);
}
console.log(`[SUCCESS] Cleanup stdout: ${stdout}`);
});
}, {
scheduled: true,
timezone: "UTC"
}); › Setup notes
Install the node-cron dependency using npm install node-cron. Run this script in a long-running process manager like PM2 to guarantee execution.
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 run_daily_reconciliation():
logger.info("Starting daily financial reconciliation task...")
try:
# Perform end-of-day transaction reconciling operations
logger.info("Daily reconciliation completed successfully.")
except Exception as e:
logger.error(f"Reconciliation task failed: {str(e)}", exc_info=True)
if __name__ == "__main__":
scheduler = BlockingScheduler()
# 45 23 * * * translates to hour=23, minute=45 daily
scheduler.add_job(
run_daily_reconciliation,
'cron',
hour=23,
minute=45,
timezone='UTC'
)
logger.info("Scheduler started. Job configured for 23:45 UTC daily.")
try:
scheduler.start()
except (KeyboardInterrupt, SystemExit):
logger.info("Scheduler stopped cleanly.") › Setup notes
Install apscheduler via pip. Run this script inside a persistent virtual environment or Docker container to maintain the daily schedule.
package main
import (
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/robfig/cron/v3"
)
func main() {
// Use UTC timezone to prevent DST issues
nyc, err := time.LoadLocation("UTC")
if err != nil {
log.Fatalf("Failed to load timezone: %v", err)
}
c := cron.New(cron.WithLocation(nyc))
// Schedule daily late-night report generation at 23:45
_, err = c.AddFunc("45 23 * * *", func() {
log.Println("Starting scheduled daily reporting job...")
if err := runDailyReport(); err != nil {
log.Printf("ERROR: Daily report job failed: %v", err)
} else {
log.Println("SUCCESS: Daily report job completed.")
}
})
if err != nil {
log.Fatalf("Error scheduling cron job: %v", err)
}
c.Start()
log.Println("Cron scheduler started for 23:45 daily...")
// Handle graceful shutdown
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<-sigChan
log.Println("Stopping cron scheduler...")
c.Stop()
}
func runDailyReport() error {
// Production logic goes here
time.Sleep(5 * time.Second)
return nil
} › Setup notes
Initialize a Go module, import github.com/robfig/cron/v3, compile the binary, and deploy it as a systemd service to run continuously.
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 LateNightTaskScheduler {
private static final Logger logger = LoggerFactory.getLogger(LateNightTaskScheduler.class);
// Cron expression for 23:45 (11:45 PM) every day.
// Spring @Scheduled cron format: "second minute hour day-of-month month day-of-week"
// We specify "0 45 23 * * *" to target the 45th minute of the 23rd hour.
@Scheduled(cron = "0 45 23 * * *", zone = "UTC")
public void executeDailyCleanup() {
logger.info("Starting scheduled daily cleanup and optimization task...");
try {
performDatabaseOptimization();
logger.info("Daily cleanup and optimization completed successfully.");
} catch (Exception e) {
logger.error("Error occurred during daily cleanup execution: ", e);
}
}
private void performDatabaseOptimization() {
// Production logic for late-night database maintenance goes here
}
} › Setup notes
Ensure @EnableScheduling is added to your main Spring Boot Application class, and place this component inside your scanned package path.
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-cleanup-2345
namespace: production
spec:
schedule: "45 23 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
jobTemplate:
spec:
template:
spec:
containers:
- name: cleanup-agent
image: postgres:15-alpine
command:
- /bin/sh
- -c
- "echo 'Starting late-night database indexing...' && psql -h db-service -U postgres -d prod_db -c 'REINDEX DATABASE prod_db;'"
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
restartPolicy: OnFailure › Setup notes
Apply this configuration file to your cluster using 'kubectl apply -f cronjob.yaml'. Ensure the referenced database credentials secret exists.
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(45 23 * * ? *) Systemd Timer
OnCalendar*-*-* 23:45:00
[Unit]
Description=Timer for cron expression: 45 23 * * *
[Timer]
OnCalendar=*-*-* 23:45:00
Persistent=true
[Install]
WantedBy=timers.target
Last verified:
Frequently Asked Questions
Why schedule a task at 23:45 instead of exactly midnight (00:00)?
Running at 23:45 staggers resource utilization, preventing contention with the high volume of automated tasks typically scheduled at exactly midnight. It also allows jobs to process and reconcile the current calendar day's data right before the date transitions.
How does Daylight Saving Time (DST) affect this schedule?
If your system uses local time, DST transitions in spring (clock forward) or autumn (clock back) can cause the job to either skip or run twice. To avoid this operational hazard, run your cron daemon or system orchestrator strictly on UTC.
What happens if the previous day's job takes more than 15 minutes?
If the task runs past midnight, it might overlap with early morning processes. It is critical to implement execution timeouts, optimize queries, and use locking mechanisms (like flock or Redis locks) to prevent concurrent executions.
Can I run this job only on weekdays?
Yes, you can modify the day-of-week field. To run at 11:45 PM from Monday through Friday, change the expression to '45 23 * * 1-5'.
How should I monitor the health of this daily job?
Implement dead man's snitches (heartbeat monitoring) where the script pings an external monitoring service upon completion. If the service doesn't receive a ping by 00:00, it triggers an alert for on-call engineers.
* Explore
Related expressions you might need
Last verified: