Skip to content

Using Spring Profiles for Multiple Spring Boot Instance Configuration

The Problem

I needed to run multiple Spring Boot instances locally for testing a distributed system. Each instance needed different ports and configuration settings, but I wasn’t sure how to manage this without duplicating code or creating messy hardcoded values.

My first thought was to just manually change the port in application.properties every time I wanted to run a different instance. That approach was tedious and error-prone - I kept forgetting which port was currently configured, and sometimes I’d accidentally start two instances on the same port.

There had to be a better way.

Understanding Spring Profiles

Spring Profiles provide a clean way to segregate parts of your application configuration and make it available only in certain environments. While I’d used profiles before for separating dev/test/prod configurations, I realized I could apply the same concept to manage multiple instances of the same application.

The key insight: each instance can have its own profile with instance-specific settings.

Creating Instance-Specific Property Files

I started by creating separate property files for each instance I wanted to run. Let’s say I need two instances - one for a primary service and one for a backup:

application-instance1.properties
server.port=8083
app.instance.name=instance-1
application-instance2.properties
server.port=8084
app.instance.name=instance-2

The naming convention is important here. Spring Boot automatically loads application-{profile}.properties when you activate a profile named {profile}. So application-instance1.properties will be loaded when I activate the profile instance1.

Activating Profiles in IntelliJ

Now I needed a way to tell Spring Boot which profile to use when starting the application. I do most of my development in IntelliJ, so I set up different run configurations for each instance.

Method 1: VM Options

In IntelliJ’s Run Configuration dialog, I added a VM option:

IntelliJ VM Options
-Dspring.profiles.active=instance1

This tells the JVM to set the system property spring.profiles.active to instance1 before the application starts.

Method 2: Program Arguments

Alternatively, you can pass it as a program argument:

Program Arguments
--spring.profiles.active=instance1

Both methods work. I prefer VM options because they’re clearly separated from application-specific arguments, but either approach is valid.

Verifying the Configuration

After setting up my run configurations, I started instance1 and checked the logs:

Console Output
2026-02-27T20:40:23,695 INFO [main] o.s.b.SpringApplication: The following 1 profile is active: "instance1"
2026-02-27T20:40:24,426 INFO [main] o.s.b.w.e.t.TomcatWebServer: Tomcat initialized with port 8083 (http)

The log confirmed that Spring loaded the instance1 profile and started Tomcat on port 8083. Then I tested with a quick curl:

Terminal
curl localhost:8083/multiple-instance/ping
Response
Instance is up and running on port 8083

Running Multiple Instances Simultaneously

With separate run configurations in IntelliJ, I could now start both instances at the same time. Each instance uses its own profile, loads its own property file, and runs on its own port.

Here’s what my setup looks like:

InstanceProfilePortRun Config Name
Primaryinstance18083MyApp-Instance1
Backupinstance28084MyApp-Instance2

Command Line Usage

If you’re running from the command line instead of IntelliJ, it’s even simpler:

Terminal
# Start instance 1
java -jar myapp.jar --spring.profiles.active=instance1
# Start instance 2 (in another terminal)
java -jar myapp.jar --spring.profiles.active=instance2

Why This Works

The beauty of this approach is that Spring’s property resolution follows a clear hierarchy. Profile-specific properties override default properties, so you get:

  1. Load application.properties (default values)
  2. Load application-{profile}.properties (override with profile-specific values)

This means I can keep common configuration in application.properties and only specify what’s different in the instance-specific files.

Common Configuration Pattern

I usually structure my properties like this:

application.properties
# Common configuration for all instances
spring.application.name=multiple-instance-demo
management.endpoints.web.exposure.include=health,info
application-instance1.properties
# Instance-specific overrides
server.port=8083
app.instance.name=instance-1

This keeps the common settings in one place and makes the instance-specific files minimal and focused.

What I Learned

Before this, I thought profiles were only for environment separation (dev/test/prod). But profiles are actually a general-purpose mechanism for any configuration that needs to vary across different runs of the same application.

The key principles:

  • Naming convention matters: application-{profile}.properties is automatically detected
  • Override, don’t duplicate: Put common config in application.properties, only override what’s different
  • One profile per purpose: Don’t mix concerns - instance profiles should only contain instance-specific settings

This approach has saved me countless headaches when testing distributed systems locally. Instead of manually editing properties files or remembering to change ports, I just select the right run configuration and go.

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!


Have you tried using Spring Profiles for other creative configuration scenarios? I’d love to hear about your use cases.

Comments