What's the difference between fixed rate and fixed delay in Spring Scheduled annotation?

  • fixedRate : makes Spring run the task on periodic intervals even if the last invocation may still be running.
  • fixedDelay : specifically controls the next execution time when the last execution finishes.

In code:

@Scheduled(fixedDelay=5000)
public void updateEmployeeInventory(){
    System.out.println("employee inventory will be updated once only the last updated finished ");
    /**
     * add your scheduled job logic here
     */
}


@Scheduled(fixedRate=5000)
public void updateEmployeeInventory(){
    System.out.println("employee inventory will be updated every 5 seconds from prior updated has stared, regardless it is finished or not");
    /**
     * add your scheduled job logic here
     */
}

"fixedRate" : waits for X millis from the start of previous execution before starting next execution. If current execution exceeds 'fixedRate' interval, the next execution is queued and this will create a series of tasks running ie multiple instances of tasks will be running.

private static int i = 0;

@Scheduled(initialDelay=1000, fixedRate=1000)
public void testScheduling() throws InterruptedException {
    System.out.println("Started : "+ ++i);
    Thread.sleep(4000);
    System.out.println("Finished : "+ i);
}

Output:

Started : 1
Finished : 1 // after 4 seconds
Started : 2 // immediately w/o waiting for 1 sec as specified in fixed rate
Finished : 2 // after 4 seconds
and so on

"fixedDelay" : waits for X millis from the end of previous execution before starting next execution. Doesn't matter how much time current execution is taking, the next execution is started after adding 'fixedDelay' interval to end time of current execution. It will not queue next execution.

private static int i = 0;

@Scheduled(initialDelay=1000, fixedDelay=1000)
public void testScheduling() throws InterruptedException {
    System.out.println("Started : "+ ++i);
    Thread.sleep(4000);
    System.out.println("Finished : "+ i);
}

Output:

Started : 1
Finished : 1 // after 4 seconds Started : 2 // waits for 1 second as specified in fixedDelay Finished : 2 // after 4 seconds Started : 3 // after 1 second
and so on


fixedRate: This is used to run the scheduled jobs in every n milliseconds. It does not matter whether the job has already finished its previous turn or not.

fixedDelay: It is used to run the scheduled job sequentially with the given n milliseconds delay time between turns. Which means, the time spent on the job will affect the start time of the next run of scheduled job.

fixedRate Example:

@Scheduled(fixedRate = 5000)
public void runJobWithFixedRate() {
...
}

Let's assume the job is triggered at 13:00:00 for the first time:

  • 1st run -> 13:00:00, job finishes at 13:00:02
  • 2nd run -> 13:00:05, job finishes at 13:00:08
  • 3rd run -> 13:00:10, job finishes at 13:00:16
  • 4th run -> 13:00:15, job finishes at 13:00:18

fixedDelay Example:

@Scheduled(fixedDelay = 5000)
public void runJobWithFixedDelay() {
...
}

Let's assume the job is triggered at 13:00:00 for the first time:

  • 1st run -> 13:00:00, job finishes at 13:00:02
  • 2nd run -> 13:00:07, job finishes at 13:00:08
  • 3rd run -> 13:00:13, job finishes at 13:00:16
  • 4th run -> 13:00:21, job finishes at 13:00:25

When to use "fixedRate": fixedRate is appropriate if it is not expected to exceed the size of the memory and the thread pool. If the incoming tasks do not finish quick, it may end up with "Out of Memory exception"

When to use "fixedDelay": If every running task is relevant to each other and they need to wait before the previous one finishes, fixedDelay is suitable. If fixedDelay time is set carefully, it will also let the running threads enough time to finish their jobs before the new task starts