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:
java -jar myapp.jar --server.port=8081This 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:
--server.port=8081 --spring.datasource.url=jdbc:mysql://localhost/db1 --spring.datasource.username=user1 --app.feature.enabled=trueThis 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:
server.port=8083spring.datasource.url=jdbc:mysql://localhost/db1spring.datasource.username=user1app.feature.enabled=trueAnd application-instance2.properties:
server.port=8084spring.datasource.url=jdbc:mysql://localhost/db2spring.datasource.username=user2app.feature.enabled=falseNow to run each instance, I just activate the profile:
java -jar myapp.jar -Dspring.profiles.active=instance1Or in IntelliJ, I add this to the VM options field:
-Dspring.profiles.active=instance1Comparison Table
After using both approaches, here’s what I learned:
| Aspect | Command-Line Arguments | Spring Profiles |
|---|---|---|
| Setup Speed | Fast - just add argument | Slower - create property files |
| Best For | Single property overrides | Multiple properties |
| Maintainability | Scattered in run configs | Centralized in files |
| Version Control | Not tracked (in IDE configs) | Tracked in source control |
| IDE Field | Program arguments | VM options |
| Reusability | Copy-paste each time | Reuse 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:
@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