Spring @Scheduled — fixedRate vs fixedDelay vs cron, plus Clustered Patterns
Fast recall
Quick revision
Core answer
TaskScheduler with adequate threads or tasks block each other. In clustered deployments @Scheduled fires on every replica — use ShedLock, Quartz clustered, or Kubernetes CronJob for single execution. Keep tasks idempotent, short, and observable.Thorough understanding of `@Scheduled` timing semantics, thread-pool config, and clustered-safety patterns
Using `fixedRate` for a slow task (overlaps pile up) or forgetting distributed locking in a cluster
Discuss `TaskScheduler` sizing, async + scheduled, error handlers, ShedLock vs Quartz tradeoffs, cron pitfalls (timezones, DST, Spring 6-field vs Unix 5-field)
Interview-ready guide
Interview answer
Spring's @Scheduled is the simplest way to run a method on a timer inside one JVM.
Three timing modes:
fixedRate— N ms between start times; can overlap with multi-thread poolfixedDelay— N ms between end and next start; never overlapscron— time-of-day expressions; Spring's 6-field format with leading seconds
Two pitfalls everyone hits:
- Default thread pool is single-threaded; multiple scheduled methods queue up
- Configure
ThreadPoolTaskSchedulerwithsetPoolSize(10), error handler, graceful shutdown - In multi-replica deployments every replica fires — duplicate runs without coordination
Cluster-safe options:
- ShedLock —
@Scheduledplus@SchedulerLock(name, lockAtMostFor, lockAtLeastFor); backed by JDBC/Redis/Mongo - Quartz clustered — heavier; rich misfire and recovery semantics
- Kubernetes CronJob — schedules outside the app; Pod runs and exits at each tick
Cron pitfalls to call out:
- Spring 6-field vs Unix 5-field — leading seconds field; common migration bug
- Timezone —
zone = "UTC"for stable infra schedules; named zones are DST-aware *in day-of-month and day-of-week is 'every day' (no AND semantics)- Feb 29 — use
L 2 *for last day of February, not29 2 *
Operational hygiene:
- Keep tasks short — delegate heavy work to a queue/Executor; method is a trigger, not the worker
- Always idempotent — failure mid-task, retries, lock expiry can cause double-runs
- Log start, end, duration, outcome with MDC
- Emit Micrometer metrics (
@Timedor manual sample); alert on missed fires (no run in 2x period) - Wrap the body in try/catch — uncaught exceptions are logged but the run is lost
Decision framework:
- Single replica → plain
@Scheduled - Multiple replicas, simple job →
@Scheduledplus ShedLock - Complex scheduling or dynamic schedules → Quartz clustered
- K8s-native, operational separation → Kubernetes CronJob
- Don't stack solutions — pick one scheduler
In an interview I'd emphasize that @Scheduled is great for in-process periodic work, but the moment you have more than one replica or need recovery semantics, graduate to ShedLock or Quartz.
Spring @Scheduled — fixedRate vs fixedDelay vs cron, plus Clustered Patterns
Direct Answer
Enable with @EnableScheduling; annotate methods with @Scheduled specifying one of: fixedRate (time between start times — overlap possible if task is slow), fixedDelay (time between end-of-last and next start — never overlaps), or cron (time-of-day expressions). The default thread pool is single-threaded; configure a TaskScheduler with adequate threads or tasks block each other. In clustered deployments @Scheduled fires on every replica — use ShedLock, Quartz clustered, or Kubernetes CronJob for single execution. Keep tasks idempotent, short, and observable.
Common Mistakes & Pitfalls
Using fixedRate for a slow task (overlaps pile up) or forgetting distributed locking in a cluster
Check your understanding
Answer these without looking back at the article.
- What's the difference between fixedRate and fixedDelay when a task takes longer than the interval?
- How does ShedLock ensure only one replica runs a scheduled task?
- When would you move from @Scheduled to Quartz or K8s CronJob?
- Why is specifying the timezone on cron expressions important?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.