Bi-Monthly on the First at Midnight | CronBase

cron expression Standard
$ 0 0 1 */2 *

At midnight on the first day of every other month

This cron expression schedules a task to run at exactly midnight on the first day of every other month. In standard cron systems, it triggers on the first of January, March, May, July, September, and November, making it ideal for bi-monthly system maintenance, database rotations, and recurring financial reporting tasks.

Minute
0
Hour
0
Day of Month
1
Month
*/2
Day of Week
*

Next 5 Runs

  • in 50d 13h
  • in 111d 13h
  • in 170d 13h
  • in 231d 13h
  • in 292d 13h

* Tools

Code & Implementations

nodejs
const cron = require('node-cron');
const { exec } = require('child_process');

// Schedule bi-monthly task at 00:00 on the 1st of every other month
// Expression: 0 0 1 */2 *
const schedule = '0 0 1 */2 *';

const task = cron.schedule(schedule, async () => {
    console.log(`[${new Date().toISOString()}] Starting bi-monthly maintenance task...`);
    try {
        // Execute the maintenance task with proper error handling and timeout
        await runMaintenance();
        console.log(`[${new Date().toISOString()}] Bi-monthly task completed successfully.`);
    } catch (error) {
        console.error(`[${new Date().toISOString()}] CRITICAL: Bi-monthly task failed:`, error);
        // In production, trigger an alert to PagerDuty, Slack, or Sentry here
    }
}, {
    scheduled: true,
    timezone: "UTC" // Force UTC to avoid Daylight Saving Time issues
});

async function runMaintenance() {
    return new Promise((resolve, reject) => {
        exec('/usr/local/bin/bi-monthly-cleanup.sh', (error, stdout, stderr) => {
            if (error) {
                reject(error);
                return;
            }
            resolve();
        });
    });
}
Setup notes

Install node-cron via npm using npm install node-cron, then run this script using Node.js to start the background scheduler 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 1 */2 ? *)

Systemd Timer

OnCalendar*-00/2-01 00:00:00

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

[Timer]
OnCalendar=*-00/2-01 00:00:00
Persistent=true

[Install]
WantedBy=timers.target

Frequently Asked Questions

Which months will this cron expression actually trigger on?

This expression triggers on the first day of every second month starting from January. Specifically, it executes on January 1st, March 1st, May 1st, July 1st, September 1st, and November 1st.

How does Daylight Saving Time affect this midnight schedule?

If your system timezone is set to a local time that observes DST, the midnight execution could run twice or be skipped entirely during clock changes. To prevent this, configure your cron daemon or scheduler to use UTC.

What is the best way to test a cron job that runs only every two months?

Since waiting two months is impractical, test your job by temporarily changing the cron pattern to run every minute (e.g., `* * * * *`) in a staging environment. Additionally, write unit tests to verify the job's core business logic independently of the cron schedule.

Can I stagger this job to avoid the standard midnight resource spike?

Yes. Many system jobs run exactly at midnight on the 1st of the month, causing database and network congestion. You can stagger this job by shifting it to run at a lower-traffic time, such as 3:30 AM (`30 3 1 */2 *`).

How should I monitor this job since it runs so infrequently?

Passive monitoring (waiting for it to fail) is highly risky for infrequent jobs. Implement active monitoring using 'Dead Man's Snitch' or healthcheck endpoints. If the external monitoring service doesn't receive a ping from your job within the expected window, it triggers an alert.

* Explore

Related expressions you might need

Was this helpful?

Last verified: