Developer guide

Spring @Scheduled cron: The 6-Field Format, Explained

The moment you write @Scheduled(cron = "...") in Spring Boot, the six fields confuse everyone coming from Linux cron. That leading seconds field is the whole story — here is how to read it, use it, and stop tripping on it.

Benjamin Rotshtein

Written by Benjamin Rotshtein

Updated

How many fields does a Spring cron expression have?

Six — Spring adds a leading seconds field to the five used by Unix cron, giving the order second, minute, hour, day-of-month, month, day-of-week. So 0 0/5 * * * * fires every 5 minutes and 0 0 9 * * MON-FRI fires weekdays at 09:00:00.

How many fields?
Six: second, minute, hour, day-of-month, month, day-of-week. Unix cron’s five fields are the same minus the leading seconds.
Every 5 minutes?
0 0/5 * * * * — second 0, then every 5th minute.
At 9am weekdays?
0 0 9 * * MON-FRI — note the 0 0 9 is second, minute, hour.

1. Six fields, seconds first

Unix cron runs at minute resolution. Spring can run tasks at any second, so it inserts a seconds field at the front. The full order is:

@Scheduled(cron = "sec min hour day-of-month month day-of-week")
//                0   1    2       3       4      5

The most common source of bugs is copying a Unix crontab line like 0 0 9 * * 1-5 (5 fields: min hour dom month dow) into Spring — Spring reads the first value as seconds, so the job fires at a different time or never fires at all. Add the missing leading 0 for seconds: 0 0 0 9 * * 1-5 is wrong too — you get the idea. The safe form is 0 0 9 * * MON-FRI.

2. The field syntax is otherwise Unix cron

Every field accepts the usual cron operators: * (any), ? (no specific value — Spring’s equivalent of not caring, common in Quartz-style schedules), , (list), - (range), / (step) and named months/days (JAN..DEC, SUN..SAT).

One trap: if you set both the day-of-month and day-of-week fields to concrete values (not * or ?), the schedule effectively matches their union — surprising to people used to Unix cron’s OR-behavior. Use ? on one of them to mean “any day”.

3. Real examples

ScheduleSpring expression
Every second* * * * * *
Every 5 seconds*/5 * * * * *
Every minute0 * * * * *
Every 5 minutes0 */5 * * * *
Every hour at minute 150 15 * * * *
Daily at 09:30:000 30 9 * * *
Weekdays at 09:00:000 0 9 * * MON-FRI
First of the month at midnight0 0 0 1 * *
At 00:00:00 every 2 hours0 0 */2 * * *

4. Pinning the timezone

A Spring cron expression is evaluated against a timezone — by default the server’s. If your container is UTC but your users are in Berlin, “09:00” means 09:00 UTC. Fix it explicitly:

@Scheduled(cron = "0 0 9 * * MON-FRI", zone = "Europe/Berlin")
public void runMorningDigest() { ... }

The same pinning protects you from daylight-saving shifts: the expression stays anchored to the zone you wrote, and Spring uses the JVM’s zone rules for that named ZoneId.

5. Use fixedDelay when you mean “wait between runs”

Cron is for wall-clock schedules. If you actually want “run every 5 minutes after the previous run finishes”, cron will queue or skip work when a run overruns. For that cadence use @Scheduled(fixedDelay = 300000) (ms) or fixedRate for a fixed start-to-start interval. Mixing the two intents is a classic source of “my Spring job runs at the wrong time”.

6. Turn the expression into plain English

Before you paste a 6-field expression into production, sanity-check what it actually means — and preview the next fire times. Use the cron to English tool (which also understands 6-field expressions) or the cron generator to build and preview schedules without guessing.

Frequently asked questions

How many fields does a Spring cron expression have?

Six, unlike the five used by Unix cron. The order is: second, minute, hour, day-of-month, month, day-of-week. So "0 0/5 * * * *" means every 5 minutes starting at second 0, and "0 0 9 * * MON-FRI" fires weekdays at 09:00:00.

What is the difference between Spring cron and Unix cron?

Unix cron uses 5 fields (minute hour day-of-month month day-of-week) and a minimum resolution of 1 minute. Spring's @Scheduled uses 6 fields because it adds a leading seconds field, so it can schedule tasks at a sub-minute interval and must be specified as a string, not in a crontab.

How do I run a Spring task every 5 seconds?

Use a six-field expression with a seconds step: @Scheduled(cron = "*/5 * * * * *"). The same pattern gives every 10 seconds (*/10 * * * * *), every 30 seconds (*/30 * * * * *) or every minute (0 * * * * *).

Does @Scheduled use the server timezone?

By default Spring schedules in the server's default timezone (or the JVM's default ZoneId). You can pin a zone explicitly on the annotation: @Scheduled(cron = "0 0 9 * * *", zone = "Europe/Berlin"). Without this, the meaning of "9am" shifts when the server clock or timezone changes.

Can Spring cron expressions use named months and days?

Yes. The month and day-of-week fields accept three-letter names (JAN..DEC, SUN..SAT) case-insensitively, for example "0 0 0 1 JAN,JUL *" to run on the first day of January and July. Lists, ranges (MON-FRI) and step values (*/15) all work like Unix cron.

Why does my Spring cron expression run at the wrong time?

Usually a missing seconds field. Unix cron is 5 fields, but Spring's first field is seconds, so a copied line like 0 9 * * * runs at second 0, minute 9, not 9 AM. Add the leading 0: 0 0 9 * * * runs at 09:00:00. Also check the zone — @Scheduled defaults to the server timezone.

Related guides

The cron cheat sheet covers the 5-field format most systems use. If a scheduled task is not running, the cron not running checklist walks through the environment pitfalls that affect cron generally.