Introduction
Both fixedRate and fixedDelay parameters are used for the parametrization of @Scheduled annotation in the Spring app. A scheduler is used to execute a method in Java using some specific time-related dynamics, for example, you can configure it to execute your method:
- on every two minutes
- 5 mins after the previous execution
- on every Monday at 13h
- every day on 15:30h
- every first day in the month
- ...
Methods with @Scheduled annotation are obliged to comply with the following rules:
- the method annotated with @Scheduled must return a void type
- the method annotated with @Scheduled should not have any input parameters
This article will discuss the usage of @Scheduled optional parameters in Spring schedulers and explain the difference between fixedRate and fixedDelay.
What does fixedDelay parameter do?
FixedDelay parameter in @Scheduled annotation adds a delay between two executions of task/method. It forces tasks to execute in sequence.
This way, method execution starts after the previous execution is completed, and fixedDelay time passed. The number you define for fixedDelay represents time in milliseconds.
@Scheduled(fixedDelay=6000)
public void callExternalService() {
...
}
If you want to add delay to the first execution of the method for some reason, you can use initialDelay parameter indicating the number of milliseconds to wait before the first execution of the method. And after that initial delay, fixed delay takes over, so methods are executed in sequence with provided fixed delay in between. So, this configuration would look like:
@Scheduled(fixedDelay=6000, initialDelay=1000)
public void callExternalService() {
...
}
What does fixedRate parameter do?
@Scheduled annotation also has a parameter called fixedRate. It should be used in situations where method invocations are independent.
@Scheduled(fixedRate=600)
public void callExternalService() {
...
}
What if my methods overlap while I use fixedRate?
If method execution should be able to overlap - execute in parallel in some moment of time, you should add @Async annotation to your service execution. Without @Async, the method will always execute after the previous execution is completed, even if fixedRate expired.
@EnableAsync
public class ExternalServiceCallExample{
@Async
@Scheduled(fixedRate = 600)
public void callExternalService(){
...
}
}
What's the difference between fixedRate and fixedDelay?
FixedDelay guarantees that executions happen in sequence and that there's a delay between the end of the previous execution and the start of the new one. With fixedRate, this is not the case. It guarantees that new execution starts after the specified time passed after the start of the previous.
FixedDelay is a good choice when you want to be sure that your executions do not overlap - so you have only one running instance at the time, so it's good for dependent jobs. On the other side, fixedRate is good for independent tasks since it could happen that X executions are running at the same time. What you should pay attention to when you use fixedRate is memory usage since you could create memory leak - too many parallel executions could eat up all your memory and your app could throw java.lang.OutOfMemoryError. So, when setting up fixedRate param, consider the chance of memory leak.