Run Jobs on the Last Day of the Month | CronBase

cron expression Standard
$ 0 0 L * *

At midnight on the last day of every month

The `0 0 L * *` cron schedule executes a task once a month at midnight on the very last day of the month, regardless of whether that month has twenty-eight, twenty-nine, thirty, or thirty-one days. It is ideal for monthly billing cycles, data archiving, and generating financial reports.

Minute
0
Hour
0
Day of Month
L
Month
*
Day of Week
*
How it works

* Tools

Code & Implementations

Bash
#!/usr/bin/env bash
# Since standard Linux cron doesn't natively support 'L',
# schedule this script to run daily (0 0 28-31 * *), and
# this guard clause will ensure the payload only runs on the last day.
set -euo pipefail

TOMORROW=$(date -d "tomorrow" +%d)
if [ "$TOMORROW" -ne 1 ]; then
    echo "Today is not the last day of the month. Exiting."
    exit 0
fi

echo "Starting end-of-month maintenance tasks..."
# Call your production payload here
# /opt/bin/run-billing-aggregation.sh
Setup notes

Save this script as run-monthly.sh, make it executable with chmod +x, and configure it to run daily at midnight (0 0 28-31 * *) in your system crontab.

Last verified:

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

Systemd Timer

OnCalendar*-*-* 00:00:00

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

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

[Install]
WantedBy=timers.target

Last verified:

Frequently Asked Questions

Does standard Linux crontab natively support the 'L' character?

No, standard Vixie cron and standard Linux crontabs do not natively support the 'L' character. Schedulers like Quartz, AWS EventBridge, and systemd-timers support it, but for standard crontab, you must run a daily script at month-end and check if tomorrow is the first.

How does this expression handle leap years in February?

If the underlying scheduler natively supports the 'L' character, it dynamically calculates leap years, running on February 29th during a leap year and February 28th otherwise. If using a daily fallback wrapper, the date utility calculates this automatically.

What timezone should I use when scheduling end-of-month jobs?

Always configure your cron daemon or orchestrator to run in Coordinated Universal Time (UTC). Using local timezones can cause your job to run twice or be skipped entirely during Daylight Saving Time (DST) transitions at month-end.

How can I prevent database locking during heavy monthly aggregations?

Avoid running heavy queries directly on your primary transactional database. Offload the data to a read-replica, use batching with small limit/offset chunks, or stream the data to an asynchronous processing queue to prevent performance degradation.

What is the best way to test a job scheduled with 'L'?

Since 'L' only occurs once a month, test your script logic by temporarily changing the cron schedule to run every minute in a staging environment, or mock the system clock in your application code to verify the date-evaluation logic.

* Explore

Related expressions you might need

Last verified:

Was this helpful?