Auto-Scaling Microservices with Eureka and Spring Boot
Last Updated :
23 Jul, 2025
Auto-scaling Microservices with Eureka and Spring Boot involves leveraging Eureka for the service discovery and Spring Boot for building microservices that can dynamically scale based on the demand. This setup allows for efficient resource utilization and it can ensure that the system can handle varying loads seamlessly.
Eureka is a service registry that allows microservices to self-register and discover new users Spring Boot can simplify the development of microservices by providing features such as embedded servers and dependency injection.
Auto-scaling configures the number of instances of microservices based on metrics such as CPU usage or incoming requests. This dynamic adjustment of resources allows the system to handle varying loads efficiently.
Key Terminologies:
- Eureka: A service registry that enables microservices to self-register and discover each other. It plays a vital role in service discovery and load balancing.
- Spring Boot: Provides an easy way to develop microservices with embedded servers and dependency injection, streamlining the development process.
- Auto-Scaling: Automatically adjusts the number of instances of a microservice based on metrics like CPU usage or incoming requests. This ensures the system can handle fluctuations in load efficiently.
Step-by-step implementation of the Auto-Scaling Microservices with Eureka and Spring Boot
Below are the steps to implement Auto-Scaling Microservices with Eureka and Spring Boot.
Set up the Eureka-server
Step 1: Create a Spring project using Spring Initializr, and include the following dependencies:
Dependencies:
- Spring Web
- Eureka Server
- Spring Dev Tools
- Lombok
After creating the Spring project, the file structure will resemble the image below.

Step 2: Open the application.properties
file and add the following code to configure the server port and Eureka server settings for the project.
spring.application.name=eureka-server-config
server.port=9099
eureka.instance.prefer-ip-address=true
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true
eureka.client.service-url.defaultZone= http://localhost:9099/eureka
Step 3: In the main class, include the annotation @EnableEurekaServer
to activate the Eureka server functionality.
Java
package org.example.eurekaserverconfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerConfigApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerConfigApplication.class, args);
}
}
pom.xml:
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>eureka-server-config</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-server-config</name>
<description>eureka-server-config</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 4: Once the Spring project is completed and run as a Spring application successfully, it will start at port 9099.

Create the User-service Microservice
Step 1: Create the Spring project using Spring Initializr. When creating the project, add the following dependencies:
Dependencies:
- Spring Web
- Eureka Server Client
- Spring Dev Tools
- Lombok
After creating the Spring project, the file structure should resemble the image below.

Step 2: Open the application.properties
file and insert the following code to configure the server port and Eureka client settings for the project.
spring.application.name=user-service
server.port=8086
management.endpoints.web.exposure.include=*
management.endpoint.metrics.enabled=true
management.prometheus.metrics.export.enabled=true
autoscaler.cpu.threshold=0.75
eureka.instance.prefer-ip-address=true
eureka.client.fetch-registry=true
eureka.client.register-with-eureka=true
eureka.client.service-url.defaultZone= http://localhost:9099/eureka
spring.data.mongodb.uri=mongodb://localhost:27017/demo
Step 3: Create a new package named "model". Within this package, create a new Java class named "User".
Go to src > org.example.userservice > model > User and put the below code.
Java
package org.example.userservice.model;
import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
private String id;
private String username;
private String email;
}
Step 4: Create the new package and it named as the repository in that package create the new Java class and it named as UserRepository .
Go to src > org.example.userservice > repository > UserRepository and put the below code.
Java
package org.example.userservice.repository;
import org.example.userservice.model.User;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends MongoRepository<User, String> {
// You can add custom query methods here if needed
}
Step 5: Create the new package and it named as the service in that package create the new Java class and it named as UserService.
Go to src > org.example.userservice > service > UserService and put the below code.
Java
package org.example.userservice.service;
import org.example.userservice.model.User;
import java.util.List;
public interface UserService {
List<User> getAllUsers();
User createUser(User user);
void deleteUser(String userId);
}
Step 6: Create the new package and it named as the service in that package create the new Java class and it named as UserServiceImpl.
Go to src > org.example.userservice > service > UserServiceImpl and put the below code.
Java
package org.example.userservice.service;
import org.example.userservice.repository.UserRepository;
import org.example.userservice.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
@Autowired
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public List<User> getAllUsers() {
return userRepository.findAll();
}
@Override
public User createUser(User user) {
return userRepository.save(user);
}
@Override
public void deleteUser(String userId) {
userRepository.deleteById(userId);
}
}
Step 7: Create a new Java class named AutoScaler.
Go to src > org.example.userservice > AutoScaler and put the below code.
Java
package org.example.userservice;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class AutoScaler {
@Value("${autoscaler.cpu.threshold}")
private double cpuThreshold;
@Value("${spring.application.name}")
private String serviceName;
@Scheduled(fixedRate = 60000) // Check every minute
public void autoScale() {
double cpuUsage = getCpuUsage(serviceName);
if (cpuUsage > cpuThreshold) {
// Scale up
System.out.println("Scaling up " + serviceName + " due to high CPU usage.");
// Trigger instance creation
scaleUp();
} else {
// Scale down
System.out.println("Scaling down " + serviceName + " due to low CPU usage.");
// Trigger instance termination
scaleDown();
}
}
private double getCpuUsage(String serviceName) {
// Placeholder for actual CPU usage metric collection
return 0.5; // Replace with real data
}
private void scaleUp() {
// Placeholder for scale-up logic
System.out.println("Scaling up the number of instances.");
}
private void scaleDown() {
// Placeholder for scale-down logic
System.out.println("Scaling down the number of instances.");
}
}
This AutoScaler class is designed to automatically scale the number of instances of the microservice based on CPU usage.
How Auto-Scaling Works:
- Monitoring: The
autoScale()
method checks CPU usage every minute. - Decision Making: If CPU usage exceeds the threshold, it triggers a scale-up; if below, it triggers a scale-down.
- Scaling Actions:
- Up-Scaling: New instances are created by interacting with a container orchestration platform (e.g., Kubernetes). The new instances register themselves with Eureka.
- Down-Scaling: Excess instances are terminated, and they de-register from Eureka to stop receiving new requests. The system ensures in-progress requests are completed.
Enhanced Implementation:
To refine auto-scaling:
- Metrics Collection: Use tools like Spring Boot Actuator and Micrometer for accurate CPU metrics.
- Scaling Algorithms: Implement more sophisticated algorithms that consider historical data and trends.
- Integration with Orchestration Platforms: Use an orchestration platform (e.g., Kubernetes) to manage instances. Integrate with its API to handle instance creation and termination dynamically.
To actually create and manage multiple instances, the AutoScaler class could be expanded like this:
Java
@Component
public class EnhancedAutoScaler {
@Value("${autoscaler.cpu.threshold.high}")
private double cpuThresholdHigh;
@Value("${autoscaler.cpu.threshold.low}")
private double cpuThresholdLow;
@Value("${autoscaler.instance.min}")
private int minInstances;
@Value("${autoscaler.instance.max}")
private int maxInstances;
@Autowired
private OrchestrationPlatformClient orchestrationClient;
@Autowired
private MetricsCollector metricsCollector;
@Scheduled(fixedRate = 60000)
public void autoScale() {
double cpuUsage = metricsCollector.getAverageCpuUsage();
int currentInstances = orchestrationClient.getCurrentInstanceCount();
if (cpuUsage > cpuThresholdHigh && currentInstances < maxInstances) {
int newInstances = Math.min(currentInstances + 1, maxInstances);
orchestrationClient.scaleToInstanceCount(newInstances);
System.out.println("Scaling up to " + newInstances + " instances due to high CPU usage.");
} else if (cpuUsage < cpuThresholdLow && currentInstances > minInstances) {
int newInstances = Math.max(currentInstances - 1, minInstances);
orchestrationClient.scaleToInstanceCount(newInstances);
System.out.println("Scaling down to " + newInstances + " instances due to low CPU usage.");
}
}
}
Additional Considerations:
- Metrics Collection: Use Spring Boot Actuator and Micrometer for real CPU metrics.
- Scaling Algorithms: Consider trends over time rather than instant values.
- Logging and Cool-Down: Add detailed logging and implement cool-down periods to prevent rapid fluctuations.
Verify Auto-Scaling
To verify auto-scaling:
- Monitoring: Check the number of running instances and metrics on your monitoring dashboard.
- Testing: Simulate high load conditions to observe the scaling behavior and ensure the system adjusts instances as expected.
Step 8: Create a new package named "controller". Within this package, create a new Java class named "UserController".
Go to src > org.example.userservice > Controller > UserController and put the below code.
Java
package org.example.userservice.controller;
import org.example.userservice.model.User;
import org.example.userservice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.getAllUsers();
return ResponseEntity.ok(users);
}
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User createdUser = userService.createUser(user);
return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
}
@DeleteMapping("/{userId}")
public ResponseEntity<Void> deleteUser(@PathVariable String userId) {
userService.deleteUser(userId);
return ResponseEntity.noContent().build();
}
}
Step 9: Run the application
Once completed the project after that run the application once runs the application successfully looks like the below image.

Eureka Dashboard:

APIS Outputs:
Create the user:
POST http://localhost//8086/api/users
Output:

Get the users:
GET http://localhost//8086/api/users
Output:

This implementation covers the basics of setting up auto-scaling for microservices using Eureka and Spring Boot. For a production-ready solution, integrate with container orchestration platforms to handle instance creation and termination dynamically based on load.