Run Monthly Jobs on the 15th at Midnight | CronBase

cron expression Standard
$ 0 0 15 * *

At midnight on the fifteenth day of each calendar month.

The `0 0 15 * *` cron expression schedules a task to execute precisely at midnight, or 12:00 AM, on the fifteenth day of every month. This specific mid-month cadence is highly effective for distributing heavy database processing, generating mid-period reports, and executing recurring monthly maintenance tasks outside of peak billing cycles.

Minute
0
Hour
0
Day of Month
15
Month
*
Day of Week
*

Next 5 Runs

  • in 3d 13h
  • in 33d 13h
  • in 64d 13h
  • in 94d 13h
  • in 125d 13h

* Tools

Code & Implementations

nodejs
const cron = require('node-cron');

// Schedule to run at midnight on the 15th of every month
cron.schedule('0 0 15 * *', async () => {
    console.log(`[${new Date().toISOString()}] Starting monthly data reconciliation...`);
    try {
        // Simulate processing logic
        await performMonthlyReconciliation();
        console.log(`[${new Date().toISOString()}] Monthly job executed successfully.`);
    } catch (error) {
        console.error(`[${new Date().toISOString()}] Critical error during monthly job:`, error);
        // Integrate with paging/alerting system here (e.g., PagerDuty, Sentry)
    }
}, {
    scheduled: true,
    timezone: "UTC"
});

async function performMonthlyReconciliation() {
    return new Promise((resolve) => setTimeout(resolve, 5000));
}
Setup notes

Install node-cron using 'npm install node-cron', save this script, and run it as a background process or PM2 daemon.

Partner UptimeRobot

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.

EventBridge Rule
cron(0 0 15 * ? *)

Systemd Timer

OnCalendar*-*-15 00:00:00

my-task.timer
[Unit]
Description=Timer for cron expression: 0 0 15 * *

[Timer]
OnCalendar=*-*-15 00:00:00
Persistent=true

[Install]
WantedBy=timers.target

Frequently Asked Questions

How do I handle daylight saving time changes at midnight?

To prevent duplicate executions or skipped runs during seasonal clock shifts, always configure your cron daemon or scheduler to run in Coordinated Universal Time (UTC) rather than local system time.

What happens if the scheduled mid-month job fails?

Because this job only runs once a month, manual intervention is usually required. Implement robust error catching to dispatch immediate alerts to Slack or PagerDuty, and ensure your script is fully idempotent so it can be safely re-run manually if it fails midway.

Why run heavy tasks on the 15th instead of the 1st?

The 1st and last days of the month are notorious for peak resource usage due to standard accounting, invoicing, and reporting runs. Scheduling on the 15th mitigates database contention by shifting heavy, non-time-critical processing to a quieter period.

How can I test this monthly job without waiting for the 15th?

You should separate your execution logic from the scheduling framework. Build your task so it can be run via an on-demand command-line flag, API endpoint, or manually triggered Kubernetes Job alongside your automated cron schedule.

Is there a risk of overlapping executions for this schedule?

With a monthly frequency, overlap is highly unlikely unless the task hangs indefinitely. Use process locks (like `flock` in Bash) or set `concurrencyPolicy: Forbid` in Kubernetes to prevent a stuck job from colliding with the next month's execution.

* Explore

Related expressions you might need

Was this helpful?

Last verified: