Spring @Scheduled Cron Guide
Spring Framework's @Scheduled annotation is the standard way to run recurring tasks in a Spring Boot application, supporting both simple fixed-interval scheduling (fixedRate, fixedDelay) and full cron expressions for calendar-based schedules — all running in-process via Spring's TaskScheduler.
Syntax Notes
Spring's cron field uses 6 fields: second, minute, hour, day-of-month, month, day-of-week — inspired by Quartz but implemented independently (Spring's own CronExpression class), so not every Quartz-specific character behaves identically.
Examples
@Scheduled(cron = "0 30 2 * * *")
public void nightlyJob() { /* ... */ }@Scheduled(fixedRate = 300000)
public void pollEvery5Minutes() { /* ... */ }@Scheduled(cron = "0 0 9 * * MON-FRI", zone = "America/New_York")
public void weekdayMorningJob() { /* ... */ }Gotchas
- Spring's cron field order (second first) is the same shape as Quartz's, but Spring implements its own parser — some Quartz-specific characters and edge-case behaviors (particularly around L and W) aren't guaranteed to behave identically, so don't assume full drop-in compatibility.
- By default, @Scheduled methods run on a single shared thread unless you configure a TaskScheduler with a larger thread pool — a slow scheduled method can delay other scheduled tasks in the same application if they share the default scheduler.
- @Scheduled only works on Spring-managed beans (a @Component, @Service, etc.) — annotating a plain unmanaged class's method silently does nothing, with no warning at startup.
Best Practices
- Configure a dedicated TaskScheduler bean with an appropriately sized thread pool if you have more than a couple of @Scheduled methods, to avoid one slow task blocking others.
- Set the `zone` attribute explicitly for anything timezone-sensitive rather than relying on the JVM's default timezone, which can vary between local development and production environments.
- Use Spring Boot Actuator's /actuator/scheduledtasks endpoint (if enabled) to inspect exactly which scheduled tasks are registered and their cron expressions at runtime — useful for verifying configuration in a running application.
Frequently Asked Questions
- What's the difference between cron, fixedRate, and fixedDelay?
- cron takes a calendar-based expression for specific times/days. fixedRate runs every N milliseconds regardless of how long the previous execution took (can overlap). fixedDelay waits N milliseconds after the previous execution finishes before starting the next one.
- Is Spring's cron syntax identical to Quartz?
- Similar in shape (6 fields, second-first) but implemented independently — Spring has its own CronExpression parser, and while common patterns work identically, edge cases around special characters aren't guaranteed to match Quartz exactly.
- Why isn't my @Scheduled method running?
- The most common cause is the class not being a Spring-managed bean, or @EnableScheduling missing from a configuration class — both fail silently with no startup error, so check those first before suspecting the cron expression itself.
Related Tools
Platform Guides
Cron syntax for Linux, Kubernetes, AWS, and more
Cron in Docker Guide
Docker has no built-in cron. See the common patterns for scheduled jobs in containers: cron inside the container, sidecar containers, and orchestrator-native scheduling.
WordPress WP-Cron Guide
WP-Cron isn't real cron — it's triggered by site visits. Learn how WordPress pseudo-cron works, why posts can be late, and how to fix it with real cron.