Spring Boot
@Scheduled
fixedRate
application.yml
configuration

Inject Scheduled fixedRate value from Spring Boot application.yml file

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you want a scheduled task interval to come from application.yml, do not try to inject a numeric field and then reference it through fixedRate. The normal Spring Boot solution is to put the value in configuration and use fixedRateString with a property placeholder.

Why fixedRateString Exists

The @Scheduled annotation has both numeric and string-based attributes. fixedRate expects a constant long value known at annotation parsing time. fixedRateString exists specifically so a property placeholder can be resolved from the Spring environment.

That is why this works:

java
@Scheduled(fixedRateString = "${jobs.cleanup.fixed-rate-ms}")

and this is the wrong shape for external configuration:

java
@Scheduled(fixedRate = someVariable)

Annotations are not regular imperative code. They need values that Spring can resolve through its annotation metadata pipeline.

Define The Value In application.yml

A minimal configuration file might look like this:

yaml
jobs:
  cleanup:
    fixed-rate-ms: 5000

The property name can be anything sensible. Using a nested prefix such as jobs.cleanup keeps scheduling settings grouped and easy to override by environment.

Use It In A Scheduled Bean

You also need scheduling enabled somewhere in the application.

java
1import java.time.Instant;
2import org.springframework.boot.SpringApplication;
3import org.springframework.boot.autoconfigure.SpringBootApplication;
4import org.springframework.scheduling.annotation.EnableScheduling;
5import org.springframework.scheduling.annotation.Scheduled;
6import org.springframework.stereotype.Component;
7
8@SpringBootApplication
9@EnableScheduling
10public class DemoApplication {
11    public static void main(String[] args) {
12        SpringApplication.run(DemoApplication.class, args);
13    }
14}
15
16@Component
17class CleanupJob {
18    @Scheduled(fixedRateString = "${jobs.cleanup.fixed-rate-ms}")
19    public void run() {
20        System.out.println("Cleanup job ran at " + Instant.now());
21    }
22}

With that setup, changing the interval is just a configuration change. No code edit is required.

fixedRate Versus fixedDelay

Make sure you choose the correct scheduling mode.

  • 'fixedRate measures from the start of one execution to the start of the next'
  • 'fixedDelay measures from the end of one execution to the start of the next'

If the task can sometimes take longer than the interval, fixedRate may cause overlapping executions unless the scheduler is constrained to one thread. If you actually need “wait five seconds after the previous run finishes,” use fixedDelayString instead.

Keep The Configuration Type Obvious

Using a property name like fixed-rate-ms is helpful because it tells readers the unit is milliseconds. That avoids silent misunderstandings when someone writes 5 and expects seconds.

If you want the value elsewhere too, bind it through @ConfigurationProperties in addition to using it in @Scheduled. But for the annotation itself, the placeholder string is still the direct mechanism.

java
1import org.springframework.boot.context.properties.ConfigurationProperties;
2
3@ConfigurationProperties(prefix = "jobs.cleanup")
4public record CleanupProperties(long fixedRateMs) {
5}

This is useful when the same setting is referenced by logs, metrics, or health reporting.

Environment Overrides

One advantage of using application.yml is that different environments can override the schedule cleanly. For example, development might run the job every five seconds, while production runs it every minute through a different profile or environment variable.

That is much safer than recompiling the application for each environment.

Common Pitfalls

The biggest pitfall is using fixedRate instead of fixedRateString. If the value comes from configuration, use the string variant.

Another mistake is forgetting @EnableScheduling. In that case the bean loads, but the job never runs, which makes the configuration look broken even though the property resolution is fine.

People also mix up milliseconds and seconds. Unless you use a convention and document it clearly, the property name itself should encode the unit.

Finally, remember that changing application.yml does not hot-reload the schedule in a normal production deployment. The application must restart or use a more advanced dynamic configuration mechanism.

Summary

  • Put the interval in application.yml and reference it with fixedRateString.
  • Use @EnableScheduling so Spring actually starts the scheduler.
  • Choose fixedRate or fixedDelay based on the job's execution semantics.
  • Make the unit explicit in the property name, such as fixed-rate-ms.
  • Configuration-based scheduling is cleaner and safer than hardcoding intervals in annotations.

Course illustration
Course illustration