Spring Bootapplication.properties
Spring Boot

application.properties

application.properties is Spring Boot's primary configuration file. It controls every aspect of your application — server settings, database connection, JPA behavior, logging, security, caching, and hundreds of auto-configuration options. Understanding the property naming conventions, profile-specific files, and the most important properties for each layer makes configuration fast and predictable.

How application.properties Works

Spring Boot reads application.properties (or application.yml) from src/main/resources at startup and uses the values to configure auto-configured beans. Every Spring Boot starter exposes a set of properties — prefixed with spring.datasource, spring.jpa, spring.security, server, management, and so on — that you use to customize its behavior without writing @Configuration code. The property system uses relaxed binding — spring.datasource.maximumPoolSize, spring.datasource.maximum-pool-size, SPRING_DATASOURCE_MAXIMUM_POOL_SIZE, and spring.datasource.maximum_pool_size all bind to the same field. This makes properties set via environment variables (common in Docker/Kubernetes) automatically compatible with properties file keys. Profile-specific files (application-dev.properties, application-prod.properties) are loaded in addition to the base file and override any matching keys. This is how a single codebase handles multiple environments.

Server Configuration

Server properties control the embedded Tomcat (or Jetty/Undertow) instance — port, context path, SSL, compression, timeouts, and connection limits.
application.properties
# ── Basic server settings ────────────────────────────────────────────
server.port=8080
server.servlet.context-path=/api       # all endpoints prefixed with /api
server.servlet.session.timeout=30m

# ── SSL / HTTPS ───────────────────────────────────────────────────────
server.ssl.enabled=true
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=changeit
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=myapp

# ── HTTP/2 ────────────────────────────────────────────────────────────
server.http2.enabled=true

# ── Response compression ──────────────────────────────────────────────
server.compression.enabled=true
server.compression.mime-types=application/json,application/xml,text/html,text/css
server.compression.min-response-size=2048

# ── Tomcat-specific tuning ────────────────────────────────────────────
server.tomcat.max-threads=200
server.tomcat.min-spare-threads=10
server.tomcat.max-connections=10000
server.tomcat.connection-timeout=5000
server.tomcat.accept-count=100

# ── Error handling ────────────────────────────────────────────────────
server.error.include-message=always
server.error.include-binding-errors=always
server.error.include-stacktrace=on_param    # only when ?trace=true in URL
server.error.include-exception=false        # never expose exception class in prod

# ── Graceful shutdown ─────────────────────────────────────────────────
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s

DataSource and Connection Pool

DataSource properties configure the database connection. Spring Boot auto-configures HikariCP — the fastest Java connection pool — from these properties.
application.properties
# ── DataSource ───────────────────────────────────────────────────────
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=${DB_PASSWORD}    # read from environment variable
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# ── HikariCP connection pool ──────────────────────────────────────────
spring.datasource.hikari.pool-name=myapp-pool
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=300000         # 5 minutes
spring.datasource.hikari.connection-timeout=20000    # 20 seconds
spring.datasource.hikari.max-lifetime=1200000        # 20 minutes
spring.datasource.hikari.keepalive-time=60000        # 1 minute
spring.datasource.hikari.validation-timeout=3000
spring.datasource.hikari.connection-test-query=SELECT 1

# ── JPA / Hibernate ───────────────────────────────────────────────────
spring.jpa.hibernate.ddl-auto=validate    # validate | update | create | create-drop | none
spring.jpa.show-sql=false                 # true in dev only
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.properties.hibernate.default_batch_fetch_size=16
spring.jpa.properties.hibernate.jdbc.batch_size=25
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.open-in-view=false             # always false — prevents lazy load issues

# ── Flyway migration ──────────────────────────────────────────────────
spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration
spring.flyway.baseline-on-migrate=false
spring.flyway.validate-on-migrate=true

# ── H2 in-memory (development only) ──────────────────────────────────
spring.datasource.url=jdbc:h2:mem:devdb;MODE=MySQL;DB_CLOSE_DELAY=-1
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

Logging Configuration

Spring Boot uses SLF4J with Logback by default. Logging properties control log levels, output format, file output, and rolling policies — no logback.xml needed for most configurations.
application.properties
# ── Log levels ────────────────────────────────────────────────────────
logging.level.root=INFO                         # default level for all loggers
logging.level.com.example=DEBUG                 # your application packages
logging.level.org.springframework.web=DEBUG     # Spring MVC request logging
logging.level.org.springframework.security=DEBUG
logging.level.org.hibernate.SQL=DEBUG           # log all SQL queries
logging.level.org.hibernate.type.descriptor.sql=TRACE   # log SQL parameters
logging.level.org.springframework.cache=DEBUG

# ── Console output format ─────────────────────────────────────────────
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%-5level) [%thread] %clr(%logger{36}){cyan} - %msg%n

# ── File output ───────────────────────────────────────────────────────
logging.file.name=logs/myapp.log
logging.file.max-size=50MB
logging.file.max-history=30              # keep 30 days of rolled files
logging.file.total-size-cap=500MB        # total cap across all rolled files

# ── File output format (different from console): ──────────────────────
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n

# ── Structured logging (Spring Boot 3.4+): ────────────────────────────
logging.structured.format.console=ecs    # Elastic Common Schema JSON format

# ── MDC (Mapped Diagnostic Context) — add to all log lines: ──────────
# logging.pattern.console=%d %-5level [%X{requestId}] %logger - %msg%n
# Set in code: MDC.put("requestId", UUID.randomUUID().toString())

# Common logger names for troubleshooting:
# org.springframework.web.servlet.DispatcherServlet   — request dispatch
# org.springframework.transaction                     — transaction boundaries
# org.springframework.data.jpa                        — JPA queries
# com.zaxxer.hikari                                   — connection pool events
# org.flywaydb                                        — migration execution

Actuator and Management

Actuator properties control which monitoring endpoints are exposed, what they show, and how they are secured.
application.properties
# ── Endpoint exposure ────────────────────────────────────────────────
management.endpoints.web.exposure.include=health,info,metrics,loggers,env,beans
management.endpoints.web.exposure.exclude=shutdown
# Expose all (development only — restrict in production):
# management.endpoints.web.exposure.include=*

# ── Health endpoint ───────────────────────────────────────────────────
management.endpoint.health.show-details=when-authorized   # always | never | when-authorized
management.endpoint.health.show-components=always
management.health.db.enabled=true
management.health.diskspace.enabled=true
management.health.redis.enabled=true

# ── Info endpoint ─────────────────────────────────────────────────────
management.info.env.enabled=true
management.info.java.enabled=true
management.info.os.enabled=true
info.app.name=My Application
info.app.version=2.1.0
info.app.description=My Spring Boot REST API

# ── Metrics ───────────────────────────────────────────────────────────
management.metrics.export.prometheus.enabled=true   # expose Prometheus metrics
management.metrics.tags.application=myapp           # tag all metrics
management.metrics.tags.environment=prod

# ── Management server (separate port for security): ───────────────────
management.server.port=8081       # actuator on different port from app
management.server.base-path=/management

# ── Loggers endpoint — change log levels at runtime: ──────────────────
management.endpoint.loggers.enabled=true
# POST /actuator/loggers/com.example  {"configuredLevel":"DEBUG"}

Custom Application Properties

Beyond Spring Boot's built-in properties, you define your own application-specific properties and bind them to typed @ConfigurationProperties classes for type safety and IDE auto-completion.
application.properties
# Custom application properties:
app.name=MyApplication
app.version=2.1.0

# JWT configuration:
app.jwt.secret=${JWT_SECRET}
app.jwt.expiration=86400
app.jwt.issuer=https://myapp.com

# Mail configuration:
app.mail.from=noreply@myapp.com
app.mail.reply-to=support@myapp.com
app.mail.templates-path=classpath:templates/email/

# Feature flags:
app.features.payments.enabled=true
app.features.notifications.enabled=true
app.features.analytics.enabled=false

# External service URLs:
app.services.inventory.url=https://inventory-service:8082
app.services.inventory.timeout=5000
app.services.pricing.url=https://pricing-service:8083
app.services.pricing.timeout=3000

# Bind to a @ConfigurationProperties class:
// @ConfigurationProperties(prefix = "app.jwt")
// public class JwtProperties {
//     private String secret;
//     private long expiration;
//     private String issuer;
//     // getters and setters
// }

# Property references — one property referencing another:
app.base-url=https://myapp.com
app.api-url=${app.base-url}/api
app.docs-url=${app.base-url}/docs

Profile-Specific Properties Files

Profile-specific files override base properties for specific environments. Spring Boot loads the profile file IN ADDITION to the base file — not instead of it.
application.properties
# ── application.properties (base — loaded for ALL profiles): ─────────
server.port=8080
spring.jpa.show-sql=false
logging.level.root=INFO
app.name=MyApplication

# ── application-dev.properties (development): ────────────────────────
spring.datasource.url=jdbc:h2:mem:devdb;MODE=MySQL
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
logging.level.com.example=DEBUG
logging.level.org.springframework.web=DEBUG

# ── application-test.properties (testing): ───────────────────────────
spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create-drop
spring.flyway.enabled=false
app.jwt.secret=test-secret-not-for-production
logging.level.root=WARN

# ── application-prod.properties (production): ────────────────────────
spring.datasource.url=${DATABASE_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
spring.datasource.hikari.maximum-pool-size=20
spring.jpa.hibernate.ddl-auto=validate
logging.level.root=WARN
logging.level.com.example=INFO
server.ssl.enabled=true
management.endpoints.web.exposure.include=health,info

# Activate a profile:
# In application.properties: spring.profiles.active=dev
# Command line: java -jar app.jar --spring.profiles.active=prod
# Environment: SPRING_PROFILES_ACTIVE=prod

Complete Reference — Most Used Properties

A quick-reference of the most commonly needed Spring Boot properties organized by category.
application.properties
# ── Spring MVC ────────────────────────────────────────────────────────
spring.mvc.format.date=yyyy-MM-dd
spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss
spring.mvc.static-path-pattern=/static/**
spring.web.resources.cache.period=3600       # 1 hour static resource cache

# ── Jackson JSON ──────────────────────────────────────────────────────
spring.jackson.serialization.write-dates-as-timestamps=false
spring.jackson.deserialization.fail-on-unknown-properties=false
spring.jackson.default-property-inclusion=non_null
spring.jackson.time-zone=UTC

# ── Spring Security ───────────────────────────────────────────────────
spring.security.user.name=admin             # default user for basic auth
spring.security.user.password=secret        # use only in development

# ── OAuth2 Resource Server ────────────────────────────────────────────
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://auth.example.com
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://auth.example.com/.well-known/jwks.json

# ── Redis ─────────────────────────────────────────────────────────────
spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.password=${REDIS_PASSWORD}
spring.data.redis.timeout=2000
spring.data.redis.lettuce.pool.max-active=8

# ── Spring Cache ──────────────────────────────────────────────────────
spring.cache.type=redis                     # redis | caffeine | simple | none
spring.cache.cache-names=users,products

# ── Async and scheduling ──────────────────────────────────────────────
spring.task.execution.pool.core-size=5
spring.task.execution.pool.max-size=20
spring.task.execution.pool.queue-capacity=100
spring.task.scheduling.pool.size=5

# ── Multipart file upload ─────────────────────────────────────────────
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=50MB

# ── DevTools ──────────────────────────────────────────────────────────
spring.devtools.restart.enabled=true
spring.devtools.livereload.enabled=true

# ── Lazy initialization ───────────────────────────────────────────────
spring.main.lazy-initialization=false

# ── Banner ────────────────────────────────────────────────────────────
spring.main.banner-mode=console             # console | log | off