Run Jobs Monthly at Noon on Day One | CronBase
0 12 1 * * At twelve o'clock noon on the first day of every month.
The `0 12 1 * *` cron expression schedules a task to execute precisely at 12:00 PM (noon) on the first day of every calendar month. This highly predictable monthly cadence is commonly utilized for generating billing statements, compiling monthly reports, resetting usage quotas, and initiating deep-archive data backups.
- Minute
- 0
- Hour
- 12
- Day of Month
- 1
- Month
- *
- Day of Week
- *
Next 5 Runs
- in 6d 15h
- in 37d 15h
- in 67d 15h
- in 98d 15h
- in 128d 15h
* Tools
Code & Implementations
# Add to /etc/cron.d/monthly-billing or user crontab
# Standard Cron syntax: Minute Hour Day-of-Month Month Day-of-Week
0 12 1 * * /usr/local/bin/generate-invoices.sh >> /var/log/cron/billing.log 2>&1 › Setup notes
Place this line in your system's crontab by running 'crontab -e'. Ensure that the target directory '/var/log/cron' exists and is writable by the executing user, or redirect logs to syslog.
const cron = require('node-cron');
// Schedule task to run at 12:00 PM on the first day of every month
cron.schedule('0 12 1 * *', () => {
try {
console.log('Starting monthly invoice generation process...');
// Implement production business logic here
} catch (error) {
console.error('Failed to execute monthly cron job:', error);
}
}, {
scheduled: true,
timezone: "UTC"
}); › Setup notes
Install node-cron via 'npm install node-cron'. We explicitly configure the timezone as UTC to avoid unexpected execution shifts during daylight saving changes.
from apscheduler.schedulers.blocking import BlockingScheduler
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
scheduler = BlockingScheduler()
@scheduler.scheduled_job('cron', day=1, hour=12, minute=0, timezone='UTC')
def monthly_backup_job():
try:
logger.info("Executing scheduled monthly backup...")
# Put production backup logic here
except Exception as e:
logger.error(f"Monthly backup job failed: {e}", exc_info=True)
if __name__ == "__main__":
scheduler.start() › Setup notes
Install apscheduler via 'pip install apscheduler'. Run this script as a persistent background daemon process to ensure execution on the first of the month.
package main
import (
"fmt"
"log"
"github.com/robfig/cron/v3"
)
func main() {
// Create a cron manager with support for standard 5-field cron specs
c := cron.New()
_, err := c.AddFunc("0 12 1 * *", func() {
log.Println("Starting monthly data aggregation pipeline...")
if err := runMonthlyPipeline(); err != nil {
log.Printf("Pipeline execution failed: %v", err)
}
})
if err != nil {
log.Fatalf("Error scheduling monthly job: %v", err)
}
c.Start()
select {} // Keep the application running
}
func runMonthlyPipeline() error {
// Simulated heavy database operation
return nil
} › Setup notes
Import the popular github.com/robfig/cron/v3 package. Ensure your application is deployed as a long-running service (such as systemd or a Docker container) so it remains active at the turn of the month.
package com.example.scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class MonthlyReportScheduler {
private static final Logger logger = LoggerFactory.getLogger(MonthlyReportScheduler.class);
// Spring's cron syntax: "second minute hour day-of-month month day-of-week"
@Scheduled(cron = "0 0 12 1 * *", zone = "UTC")
public void runMonthlyReport() {
logger.info("Starting monthly financial report generation...");
try {
// Execute complex business logic
generateLedger();
} catch (Exception e) {
logger.error("Error executing monthly report generation: ", e);
}
}
private void generateLedger() {
// Implementation details
}
} › Setup notes
Ensure you have '@EnableScheduling' declared on your main Spring Boot configuration class. Note that Spring's cron expression requires six fields (including seconds).
apiVersion: batch/v1
kind: CronJob
metadata:
name: monthly-data-cleanup
namespace: production
spec:
schedule: "0 12 1 * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
jobTemplate:
spec:
template:
spec:
containers:
- name: cleanup-worker
image: registry.example.com/data-cleaner:v1.2.0
env:
- name: ENV
value: "production"
restartPolicy: OnFailure › Setup notes
Save this manifest to a file like 'monthly-job.yaml' and apply it using 'kubectl apply -f monthly-job.yaml'. Setting 'concurrencyPolicy: Forbid' prevents overlapping runs in case a job takes longer than expected.
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 12 1 * ? *) Systemd Timer
OnCalendar*-*-01 12:00:00
[Unit]
Description=Timer for cron expression: 0 12 1 * *
[Timer]
OnCalendar=*-*-01 12:00:00
Persistent=true
[Install]
WantedBy=timers.target
Last verified:
Frequently Asked Questions
What happens if the server is offline at exactly 12:00 PM on the first?
Standard cron daemons do not catch up on missed executions. If your server is offline during the execution window, the job will not run until the first of the following month. For critical tasks, use tools like Anacron, or design your job to check for missing historical runs upon startup.
How does Daylight Saving Time (DST) affect a job running at noon?
Scheduling jobs at 12:00 PM is highly resilient to DST shifts, as transitions almost exclusively occur during early morning hours (typically 1:00 AM to 3:00 AM). However, if your system is configured to run on UTC but your business operates on local time, the local execution hour will shift by one hour twice a year.
How should I handle long-running processes that take hours to complete?
Since this job runs only once a month, overlapping executions are rare. However, if the process is extremely heavy, ensure you configure concurrency limits (e.g., concurrencyPolicy: Forbid in Kubernetes) and set an explicit application-level timeout to prevent orphaned database connections or memory leaks.
Can I run this schedule on the last day of the month instead of the first?
Standard cron does not natively support an 'L' (Last) character to target the last day of the month. To run on the last day, you must either schedule the job to run daily and use an inline shell script check (e.g., checking if tomorrow is the first), or use advanced cron dialects like Quartz.
How do I test a monthly cron job without waiting an entire month?
Do not wait for the real schedule. You can test the job by temporarily modifying the cron pattern to run every few minutes in a staging environment. Alternatively, decouple your business logic into a separate script or CLI command that can be triggered manually on-demand during verification.
* Explore
Related expressions you might need
Last verified: