Skip to content

How to Test Spring Boot Applications with Multiple Local Instances

I needed to test how two Spring Boot applications communicate with each other locally. I kept starting one instance, stopping it, changing the port, and starting it again. This was tedious and didn’t let me test actual inter-service communication.

Here’s how I solved this problem and set up multiple local Spring Boot instances for proper integration testing.

The Problem

I was building a microservices architecture where Service A calls Service B. Testing this locally meant I needed both services running simultaneously. My initial approach:

  1. Start Service A on port 8081
  2. Stop Service A
  3. Change config to port 8082
  4. Start Service B
  5. Try to remember what Service A was supposed to do

This didn’t work for obvious reasons. I couldn’t test actual HTTP calls between services because only one was running at a time.

Solution: Multiple IntelliJ Run Configurations

The key insight is that you can create multiple run configurations for the same Spring Boot application, each with different configuration parameters.

Step 1: Create a Verification Endpoint

First, I added a simple endpoint to verify which instance is running. This became invaluable for debugging.

MultipleInstanceController.java
@RestController
@RequestMapping("/multiple-instance")
public class MultipleInstanceController {
@Value("${server.port}")
private String port;
@Value("${app.instance.name:default}")
private String instanceName;
@GetMapping("/ping")
public ResponseEntity<String> ping() {
return ResponseEntity.ok("Instance is up and running on port " + port);
}
@GetMapping("/info")
public ResponseEntity<Map<String, String>> info() {
return ResponseEntity.ok(Map.of(
"port", port,
"instance", instanceName,
"timestamp", Instant.now().toString()
));
}
}

The @Value annotations inject the port and instance name from configuration. The :default syntax provides a fallback value if app.instance.name isn’t configured.

Step 2: Create Multiple Application Properties

I created separate properties files for each instance.

application-instance1.properties
server.port=8081
app.instance.name=instance1
spring.application.name=service-a
application-instance2.properties
server.port=8082
app.instance.name=instance2
spring.application.name=service-b

Step 3: Configure IntelliJ Run Configurations

In IntelliJ IDEA, I created separate run configurations:

  1. Go to Run > Edit Configurations
  2. Click the + button and select “Spring Boot”
  3. Name it “Instance1”
  4. Set Main class to your application class
  5. In “Active profiles” or “VM options”, add: -Dspring.profiles.active=instance1

Repeat for Instance2 with -Dspring.profiles.active=instance2.

Alternatively, you can override properties directly in VM options:

VM Options for Instance1
-Dserver.port=8081 -Dapp.instance.name=instance1
VM Options for Instance2
-Dserver.port=8082 -Dapp.instance.name=instance2

Step 4: Start Multiple Instances

Now I can start both configurations. IntelliJ lets you run multiple configurations simultaneously by selecting “Run All” or by starting each one individually.

After starting both instances, I verified they were running correctly.

Verifying Instances with curl

I used curl to confirm each instance was responding on its expected port.

Terminal
curl localhost:8081/multiple-instance/ping

Output:

Response
Instance is up and running on port 8081

Then the second instance:

Terminal
curl localhost:8082/multiple-instance/ping

Output:

Response
Instance is up and running on port 8082

The /info endpoint gives more detailed information:

Terminal
curl localhost:8081/multiple-instance/info

Output:

Response
{
"port": "8081",
"instance": "instance1",
"timestamp": "2026-03-26T10:15:30.123Z"
}

Testing Inter-Instance Communication

With both instances running, I could finally test actual HTTP calls between them. From instance1, I called instance2:

Terminal
curl -X POST http://localhost:8082/api/process \
-H "Content-Type: application/json" \
-d '{"data": "test from instance1"}'

This worked because both instances were running simultaneously. Previously, this would have failed because nothing was listening on port 8082.

Automating Verification

I created a simple bash script to check all instances at once:

check-instances.sh
#!/bin/bash
for port in 8081 8082 8083 8084; do
echo "Checking port $port..."
curl -s localhost:$port/multiple-instance/ping || echo " - Not responding"
done

Output:

Response
Checking port 8081...
Instance is up and running on port 8081
Checking port 8082...
Instance is up and running on port 8082
Checking port 8083...
- Not responding
Checking port 8084...
- Not responding

Why This Approach Works

The verification endpoint pattern serves three purposes:

  1. Quick Health Check: The /ping endpoint confirms the instance is running without complex logic.

  2. Instance Identification: The /info endpoint shows which configuration the instance is using, which helps debug port conflicts or configuration issues.

  3. Integration Testing: With all instances running, you can test actual HTTP communication between them, simulating a real microservices environment.

Common Issues I Encountered

Port Already in Use: If you forget to stop an instance, starting another on the same port fails. I fixed this by always checking which instances are running first.

Wrong Configuration Applied: Sometimes I thought I was running instance1 but actually had instance2’s configuration. The /info endpoint made it easy to verify which config was active.

Cache Issues: IntelliJ sometimes cached old run configuration settings. I resolved this by invalidating caches (File > Invalidate Caches) when configurations didn’t update properly.

Final Thoughts

Running multiple Spring Boot instances locally transforms how you test microservices. Instead of mocking everything, you can test real HTTP communication, verify load balancing, and catch integration issues early in development.

The verification endpoint pattern is simple but invaluable. It takes five minutes to add and saves hours of debugging time when you’re unsure which instance is responding or whether your configuration is correct.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments