Spring Boot Best Practices for Production
Conference · 28 January 2025
Running Spring Boot in production is more than just java -jar. Here are practices that pay off: externalized config, health checks, and structured logging.
1. Externalize configuration
Never hardcode environment-specific values. Use application.yml (or .properties) and override with env vars or config server.
# application.yml – defaults
server:
port: 8080
spring:
datasource:
url: ${DATABASE_URL:jdbc:postgresql://localhost:5432/app}
username: ${DB_USER:app}
password: ${DB_PASSWORD:}
Override in production:
export DATABASE_URL=jdbc:postgresql://db.prod:5432/app
export DB_USER=app
export DB_PASSWORD=secret
java -jar app.jar
Twelve-Factor style: config in the environment, not in the repo.
2. Health and readiness
Expose health and readiness so orchestrators know when to send traffic:
management:
endpoints:
web:
exposure:
include: health,info
endpoint:
health:
show-details: when-authorized
health:
livenessState:
enabled: true
readinessState:
enabled: true
- Liveness – is the process alive? (restart if not.)
- Readiness – is the app ready for traffic? (e.g. DB up, caches warm.)
Kubernetes uses these for livenessProbe and readinessProbe.
3. Structured logging
Use a structured format (e.g. JSON) so log aggregators can index and query:
logging:
pattern:
console: "{\"time\":\"%d{yyyy-MM-dd HH:mm:ss.SSS}\",\"level\":\"%level\",\"logger\":\"%logger\",\"msg\":\"%msg\"}\n"
In code, use SLF4J with placeholders (no string concatenation):
log.info("Request processed: requestId={}, durationMs={}", requestId, duration);
4. Graceful shutdown
Allow in-flight requests to finish before the JVM exits:
server:
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30s
Kubernetes sends SIGTERM; with graceful shutdown, your app stops accepting new requests and waits for current ones (up to the timeout).
Summary
- Config – env vars and externalized config; no secrets in code.
- Health – liveness and readiness endpoints for orchestrators.
- Logging – structured (e.g. JSON) and with placeholders.
- Shutdown – graceful so load balancers and orchestrators can drain traffic.
These practices keep Spring Boot apps observable, configurable, and safe to deploy and scale.