Unlock Spring Boot: Hidden Default Settings That Can Crash Your App

This article reveals the hidden default configurations of Spring Boot—such as Tomcat connection limits, HikariCP pool sizes, Jackson timezone handling, logging, caching, file upload limits, async thread pools, static resource caching, and transaction timeouts—and provides practical YAML adjustments to prevent performance bottlenecks and production failures.

macrozheng
macrozheng
macrozheng
Unlock Spring Boot: Hidden Default Settings That Can Crash Your App

Introduction

When Spring Boot first appeared it was praised for “convention over configuration”, but many of its defaults can become hidden traps in production.

Tomcat Connection Pool

Spring Boot uses Tomcat as the embedded web server. The default max connections and threads are 200, which is insufficient for high concurrency.

server:
  tomcat:
    max-connections: 10000 # maximum connections
    threads:
      max: 800            # maximum worker threads
      min-spare: 100      # minimum idle threads
    accept-count: 100     # queue length
    connection-timeout: 20000

The default connection timeout is unlimited, causing connections to stay open indefinitely.

Database Connection Pool

Spring Boot defaults to HikariCP with a maximum pool size of 10, which is too small for most production workloads.

spring:
  datasource:
    hikari:
      maximum-pool-size: 50
      minimum-idle: 10
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      leak-detection-threshold: 60000

Enable leak detection to surface hidden connection leaks.

JPA Lazy Loading

JPA lazy loading can cause N+1 query problems. Use @EntityGraph or JOIN FETCH to fetch associations efficiently.

@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders")
List<User> findAllWithOrders();

Jackson Timezone Serialization

Jackson uses the system timezone by default, leading to inconsistent timestamps across servers.

spring:
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
    serialization:
      write-dates-as-timestamps: false

Log Configuration

Logback’s default configuration does not rotate or limit log files, which can fill disk space.

logging:
  file:
    name: app.log
  logback:
    rollingpolicy:
      max-file-size: 100MB
      max-history: 30
      total-size-cap: 3GB

Adjust log levels to reduce noise in production.

Cache Configuration

The default @Cacheable implementation uses a simple ConcurrentHashMap without expiration. Switching to Caffeine provides size limits and TTL.

spring:
  cache:
    type: caffeine
    caffeine:
      spec: maximumSize=10000,expireAfterWrite=600s

Monitoring Endpoints

Spring Boot Actuator exposes many endpoints; expose only the necessary ones and secure them.

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      show-details: when-authorized

File Upload Size Limits

The default limits (1 MB per file, 10 MB total) are often too low.

spring:
  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 100MB
      file-size-threshold: 2KB
      location: /tmp
      resolve-lazily: false

Adjust file-size-threshold to balance memory and disk usage.

Async Thread Pool Configuration

Using @Async defaults to SimpleAsyncTaskExecutor, which creates a new thread per task. Configure a bounded thread pool.

spring:
  task:
    execution:
      pool:
        core-size: 8
        max-size: 16
        queue-capacity: 100
        keep-alive: 60s
        thread-name-prefix: async-task-
    scheduling:
      pool:
        size: 4
        thread-name-prefix: scheduling-

Static Resource Caching Strategy

By default Spring Boot does not set HTTP cache headers for static assets, causing browsers to re‑download them on every request.

spring:
  web:
    resources:
      cache:
        cachecontrol:
          max-age: 365d
        cache-public: true
        chain:
          strategy:
            content:
              enabled: true
        paths: /**
        cache: true
        static-locations: classpath:/static/

Enabling content versioning adds a hash to filenames, allowing browsers to cache unchanged files.

Database Transaction Timeout

Long‑running @Transactional methods hold database locks. Set a timeout and split large batches into smaller transactions.

@Transactional(timeout = 30, rollbackFor = Exception.class)
public void batchProcess(List<Data> dataList) {
    int batchSize = 100;
    for (int i = 0; i < dataList.size(); i += batchSize) {
        List<Data> batch = dataList.subList(i, Math.min(i + batchSize, dataList.size()));
        processBatch(batch);
    }
}

Conclusion

Spring Boot’s “convention over configuration” saves effort, but each default carries assumptions that may not fit every scenario. Proactively reviewing and tuning these settings helps avoid hidden pitfalls and keeps production systems stable.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaperformanceoptimizationConfigurationSpring Boot
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.