Skip to content

Command Line Arguments vs Spring Profiles in Spring Boot: When to Use Each

I needed to run two instances of my Spring Boot application locally - one on port 8080 and another on port 8081. I had no idea which approach was better: command-line arguments or Spring Profiles. After trying both, I finally understood when to use each.

The Problem

I was developing a feature that required two application instances running simultaneously. My first instinct was to override the port using a command-line argument:

Terminal
java -jar myapp.jar --server.port=8081

This worked great for the port. But then I needed to configure different databases, different cache settings, and feature flags for each instance. My command-line arguments started looking messy:

Program arguments field in IntelliJ
--server.port=8081 --spring.datasource.url=jdbc:mysql://localhost/db1 --spring.datasource.username=user1 --app.feature.enabled=true

This felt wrong. I kept thinking there had to be a better way.

Enter Spring Profiles

I realized I needed Spring Profiles when the configuration grew beyond a few properties. Instead of scattering everything across command-line arguments, I could centralize them in property files.

I created application-instance1.properties:

application-instance1.properties
server.port=8083
spring.datasource.url=jdbc:mysql://localhost/db1
spring.datasource.username=user1
app.feature.enabled=true

And application-instance2.properties:

application-instance2.properties
server.port=8084
spring.datasource.url=jdbc:mysql://localhost/db2
spring.datasource.username=user2
app.feature.enabled=false

Now to run each instance, I just activate the profile:

Terminal
java -jar myapp.jar -Dspring.profiles.active=instance1

Or in IntelliJ, I add this to the VM options field:

VM options field in IntelliJ
-Dspring.profiles.active=instance1

Comparison Table

After using both approaches, here’s what I learned:

AspectCommand-Line ArgumentsSpring Profiles
Setup SpeedFast - just add argumentSlower - create property files
Best ForSingle property overridesMultiple properties
MaintainabilityScattered in run configsCentralized in files
Version ControlNot tracked (in IDE configs)Tracked in source control
IDE FieldProgram argumentsVM options
ReusabilityCopy-paste each timeReuse profiles across runs

When to Use Each

Use command-line arguments when:

  • You need a quick, one-time override
  • You’re testing a single property change
  • You don’t want to create a new profile for a temporary configuration

Use Spring Profiles when:

  • You have multiple related properties to configure
  • You’re setting up different environments (dev, staging, prod)
  • You need to run multiple instances with different configurations
  • You want configurations tracked in version control

Verification

I added a simple endpoint to verify both approaches work:

MultipleInstanceController.java
@RestController
@RequestMapping("/multiple-instance")
public class MultipleInstanceController {
@Value("${server.port}")
private String port;
@GetMapping("/ping")
public ResponseEntity<String> ping() {
return ResponseEntity.ok("Instance is up and running on port " + port);
}
}

Both approaches correctly set the port and other properties.

Key Takeaway

Command-line arguments are perfect for quick, simple overrides. Spring Profiles shine when complexity grows. I now use command-line arguments for testing single properties during development, and Spring Profiles for any configuration I need to run repeatedly or track in version control.

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