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:
server.port=8083app.instance.name=instance-1server.port=8084app.instance.name=instance-2The 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:
-Dspring.profiles.active=instance1This 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:
--spring.profiles.active=instance1Both 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:
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:
curl localhost:8083/multiple-instance/pingInstance is up and running on port 8083Running 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:
| Instance | Profile | Port | Run Config Name |
|---|---|---|---|
| Primary | instance1 | 8083 | MyApp-Instance1 |
| Backup | instance2 | 8084 | MyApp-Instance2 |
Command Line Usage
If you’re running from the command line instead of IntelliJ, it’s even simpler:
# Start instance 1java -jar myapp.jar --spring.profiles.active=instance1
# Start instance 2 (in another terminal)java -jar myapp.jar --spring.profiles.active=instance2Why 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:
- Load
application.properties(default values) - 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:
# Common configuration for all instancesspring.application.name=multiple-instance-demomanagement.endpoints.web.exposure.include=health,info# Instance-specific overridesserver.port=8083app.instance.name=instance-1This 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}.propertiesis 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