Spring Boot profiles are a powerful way to control your application’s configuration and behavior across different environments — local development, testing, staging, and production.
In this guide you’ll learn:
- How to define profile-specific properties
- How to activate profiles safely
- How profiles affect bean loading
- Real examples with YAML and properties
- Production best practices
This article is written for developers who want practical, real-world usage, not just academic explanations.
What Are Spring Profiles?
A Spring profile is a named configuration set that Spring Boot activates at runtime.
It allows you to define different settings for different environments, such as:
devfor local developmenttestfor QA or integration environmentsprodfor production
Profiles help you run the same codebase with different behavior depending on where your app runs.
How Spring Boot Loads Profile Configurations
Spring Boot reads configuration from multiple sources, but profiles allow you to override only what’s necessary.
For example:
application.yml— common settingsapplication-dev.yml— dev overridesapplication-prod.yml— prod overrides
Spring Boot applies configurations in the following order:
- Default config (
application.yml/properties) - Profile-specific config
- Environment variables
- Command-line arguments
For a deeper dive into configuration loading order, see:
https://springbootfixes.com/spring-boot-configuration-loading-order-production-guide/
Defining Profile-Specific Configuration
Example – YAML
application.yml
spring:
datasource:
url: jdbc:mysql://common-db:3306/app
username: commonuser
application-dev.yml
spring:
datasource:
url: jdbc:h2:mem:devdb
username: devuser
application-prod.yml
spring:
datasource:
url: jdbc:mysql://prod-db:3306/app
username: produser
With profiles active:
devloadsapplication-dev.ymloverriding shared valuesprodloadsapplication-prod.yml
Activating Spring Boot Profiles
Profile activation can be done in three common ways:
1. Environment Variable (Best Practice for Production)
export SPRING_PROFILES_ACTIVE=prod
2. Command-Line Argument
java -jar app.jar --spring.profiles.active=dev
3. application.properties (dev only)
spring.profiles.active=dev
Important: Avoid hardcoding profiles in config for production environments. Instead, use external settings such as environment variables.
Using @Profile to Load Beans Conditionally
Profiles not only control properties — they also control which beans are created.
Example – Service per Profile
@Service
@Profile("dev")
public class MockEmailService implements EmailService {}
@Service
@Profile("prod")
public class SmtpEmailService implements EmailService {}
Spring will only load the bean that matches the active profile.
This pattern is especially useful for:
- Mocking components in dev and test
- Using real integrations in prod
- Feature toggles during rollout
Multiple Active Profiles
Spring Boot supports activating multiple profiles:
SPRING_PROFILES_ACTIVE=dev,cloud
When multiple profiles are active:
- Profile configs are merged based on order
- Later values override earlier ones
- Unpredictable overrides should be avoided
Profile-Specific Bean Grouping
Profiles can also be used at configuration class level:
@Configuration
@Profile("test")
public class TestDatabaseConfig {}
This keeps configuration tidy and scoped to specific environments.
Real-World Example — Dev vs Prod
Dev Environment
SPRING_PROFILES_ACTIVE=dev
- In-memory database (H2)
- Debug logs
- Mock services
- Local storage
Prod Environment
SPRING_PROFILES_ACTIVE=prod
- Real RDBMS
- Minimal logs
- Secure credentials via secrets manager
- Monitoring enabled
This separation ensures:
✔ No accidental use of prod services in dev
✔ Predictable behavior
✔ Cleaner deployments
Profiles With Externalized Configuration
In cloud or container environments (such as Kubernetes), configuration is often passed as environment variables or external config mounts.
Example:
SPRING_DATASOURCE_URL=jdbc:mysql://prod-db:3306/app
SPRING_PROFILES_ACTIVE=prod
Spring Boot will pick these up automatically.
Common Profile Mistakes
❌ Hardcoding Production Profile in Code
This leads to config leaks and makes deployments fragile.
❌ Too Many Profiles Without Clear Purpose
Use only meaningful profiles (dev, test, prod, maybe staging).
❌ Mismatched Property Keys Between Files
Property names must remain consistent across profile files.
When Profiles Are Not Enough
Profiles manage environment separation, but in large systems, you may need:
- Feature flags (rollouts, experiments)
- Centralized config servers (Spring Cloud Config)
- Secret managers (Vault, AWS Secrets Manager)
Profiles are the foundation — not the entire solution.
Related Spring Boot Guides
To strengthen your understanding of profiles, check these:
- Spring Boot Configuration and Profiles Explained
https://springbootfixes.com/spring-boot-configuration-and-profiles-explained-beginner-to-production-guide/ - Spring Boot Startup Flow Explained
https://springbootfixes.com/how-spring-boot-application-starts-startup-flow-explained/ - Spring Boot Dependency Injection
https://springbootfixes.com/dependency-injection-in-spring-boot-production-grade-explanation/ - Spring Boot Bean Lifecycle
https://springbootfixes.com/how-spring-boot-creates-beans-bean-lifecycle-simplified-for-production/
FAQ — Spring Profiles
Can I activate multiple profiles at once?
Yes — separate them with commas:
SPRING_PROFILES_ACTIVE=dev,cloud
Do profiles work with application.properties and application.yml?
Yes — profiles work in both formats.
Should I use profiles for feature flags?
Not recommended — profiles are environment scopes, not feature toggles.
Summary
Spring Boot profiles are essential for real-world applications because they let you:
✔ Separate environments cleanly
✔ Manage different behavior without code changes
✔ Control beans with @Profile
✔ Override configurations safely
If you’re serious about scaling Spring Boot applications to production, mastering profiles is mandatory.
