Monthly
0 0 28-31 * *Run at the end of every month (approximated by days 28-31).
This preview is live: the table below shows the actual next run times for 0 0 28-31 * * in your time zone, recomputed in your browser. Change the expression, dialect, or zone to experiment, then copy the result.
0 0 28-31 * * meansThe true last day of the month varies (28, 29, 30, or 31), and plain Unix cron cannot express "the last day" directly. The common workaround is 0 0 28-31 * * plus a one-line guard in the job that checks whether tomorrow is the 1st, only then does the real work run.
Month-end is when the books close: final reconciliations, end-of-month reports, and billing true-ups. Getting the "last day" right matters because firing a day early (always on the 28th) would close February correctly but every other month a few days too soon.
Unix cron has five fields. Here is what each one is doing in this expression:
| Field | Value | Meaning |
|---|---|---|
| Minute | 0 | minute = 0 |
| Hour | 0 | hour = 0 |
| Day of month | 28-31 | the range 28-31 (inclusive) of day-of-month |
| Month | * | every month |
| Day of week | * | every day-of-week |
The same cadence written for the seven cron dialects you are most likely to meet. Copy the line for the system you target, the field count and day-of-week numbering differ between them.
| Scheduler | Expression | Copy |
|---|---|---|
| Unix / crontab | 0 0 28-31 * * | |
| GitHub Actions | 0 0 28-31 * * | |
| Kubernetes CronJob | 0 0 28-31 * * | |
| Vercel Cron | 0 0 28-31 * * | |
| Quartz | 0 0 0 28-31 * ? * | |
| Spring | 0 0 0 28-31 * ? | |
| AWS EventBridge | 0 0 28-31 * ? * |
Dialect note: Quartz and EventBridge support L for last-day-of-month: 0 0 0 L * ? (Quartz), 0 0 L * ? * (EventBridge). Unix, GitHub Actions, Kubernetes, Spring, and Vercel need the 28-31 guard trick.
0 0 28-31 * *0 0 28-31 * * fires on up to four days. Gate the real work with a check like [ "$(date -d tomorrow +%d)" = 01 ] so it runs only on the actual last day. Dialects with L (Quartz, EventBridge) avoid the hack entirely.
0 0 28-31 * * means: Run at the end of every month (approximated by days 28-31). The true last day of the month varies (28, 29, 30, or 31), and plain Unix cron cannot express "the last day" directly. The common workaround is 0 0 28-31 * * plus a one-line guard in the job that checks whether tomorrow is the 1st, only then does the real work run.
Use 0 0 28-31 * * in the schedule's cron field. 0 0 28-31 * * fires on up to four days. Gate the real work with a check like [ "$(date -d tomorrow +%d)" = 01 ] so it runs only on the actual last day. Dialects with L (Quartz, EventBridge) avoid the hack entirely.
EventBridge uses six fields with a required year and a ? placeholder in one day field: 0 0 28-31 * ? *. Wrap it as cron(0 0 28-31 * ? *) in the console or CloudFormation.
Quartz is seconds-first with a trailing year, so the equivalent is 0 0 0 28-31 * ? *. Remember Quartz numbers Sunday as 1, the opposite of Unix.
Browse the full set of cron pattern pages, or jump to the interactive tools: the cron expression builder for designing a schedule from scratch, the cron cheat sheet for a side-by-side reference, the cron timezone translator for moving a schedule between zones and dialects, and the GitHub Actions cron picker for DST-stable CI schedules.