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.