@Scheduled — fixedRate, fixedDelay, cron. Difference betw… — Cracked Java
// Spring Framework & Spring Boot · Async, Scheduling, Virtual Threads
SeniorCodingTrick

@Scheduled — fixedRate, fixedDelay, cron. Difference between fixedRate and fixedDelay.

@Scheduled tells Spring to call a method on a clock, in one of three modes — fixedRate, fixedDelay, or cron — and the difference between fixedRate and fixedDelay (start-to-start vs end-to-start) is the part interviewers test. Enable it with @EnableScheduling (Boot auto-enables when it finds a @Scheduled method). The method must take no arguments and typically returns void.

The three triggers

@Scheduled(fixedRate = 5000)          // every 5s, measured start-to-start
public void poll() { ... }

@Scheduled(fixedDelay = 5000)         // 5s gap AFTER each run finishes
public void cleanup() { ... }

@Scheduled(cron = "0 0 2 * * *", zone = "UTC")   // 02:00 every day
public void nightlyReport() { ... }

fixedRate vs fixedDelay — the core distinction

  • fixedRate schedules the next start a fixed interval after the previous start. If a run takes longer than the interval, the next one is due immediately (and, on a multi-thread scheduler, could even overlap). It targets a steady frequency.
  • fixedDelay waits a fixed interval after the previous run finishes before starting the next. Runs never overlap; the effective period is delay + execution time. It targets a steady gap between runs.

Example: a task that takes 8s with a 5s interval. fixedRate tries to fire every 5s (so the next is overdue and runs back-to-back); fixedDelay runs at roughly 13s spacing (8s work + 5s rest).

Use fixedDelay for cleanup/polling where you want breathing room and no overlap; fixedRate when you genuinely need a fixed cadence and the task is shorter than the interval. Add initialDelay to defer the first run.

The default scheduler is single-threaded

This bites people. By default Spring uses a one-thread ThreadPoolTaskScheduler, so all @Scheduled methods share it — a slow task blocks every other scheduled task, including unrelated ones. Fix by enlarging the pool:

spring.task.scheduling.pool.size=5

(or define a TaskScheduler bean / implement SchedulingConfigurer).

Mark your status