Avoid Hidden SpringBoot Pitfalls: Optimize Default Configurations for Production

This article reveals how SpringBoot's out‑of‑the‑box defaults—such as Tomcat connection limits, HikariCP pool size, JPA lazy loading, Jackson timezone handling, logging, file upload limits, async thread pools, static resource caching, and transaction timeouts—can cause performance bottlenecks and stability issues in production, and provides concrete configuration recommendations to prevent them.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Avoid Hidden SpringBoot Pitfalls: Optimize Default Configurations for Production

Introduction

When SpringBoot first emerged, its "convention over configuration" promise attracted many developers, but the hidden defaults often become performance traps in real‑world deployments.

Tomcat Connection Pool

SpringBoot uses Tomcat as the default web container, but the default maximum connections (200) and threads (200) are insufficient for high‑concurrency traffic.

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

The default timeout is unlimited, causing connections to linger and exhaust resources.

Database Connection Pool

SpringBoot defaults to HikariCP with a maximum pool size of 10, which is too low 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

Enabling leak-detection-threshold helps detect connection leaks.

JPA Lazy Loading

SpringBoot enables lazy loading by default, which can cause N+1 query problems.

@Entity
public class User {
    @Id
    private Long id;
    @OneToMany(fetch = FetchType.LAZY)
    private List<Order> orders;
}

To avoid N+1 queries, use @EntityGraph or JOIN FETCH in repository methods:

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

Jackson Timezone Serialization

Jackson defaults to the system timezone, 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

Explicit timezone configuration prevents serialization mismatches in distributed environments.

Log Configuration

Logback’s default settings lack file rotation and size limits, causing log files to grow indefinitely.

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 ConcurrentHashMap without expiration, risking memory overflow.

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

Caffeine provides better performance and eviction policies.

Monitoring Endpoints

SpringBoot Actuator exposes many endpoints that may leak sensitive information.

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

Expose only necessary endpoints and secure them.

File Upload Size Limits

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

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.

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-

Configure core and max sizes based on CPU‑bound or IO‑bound workloads.

Static Resource Caching

SpringBoot does not set HTTP cache headers for static assets, causing browsers to re‑download unchanged files.

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 (e.g., style-abc123.css) allows browsers to cache assets effectively.

Database Transaction Timeout

Without a timeout, long‑running transactions hold locks and can block other operations.

@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);
    }
}

Splitting large jobs into smaller transactions releases locks sooner.

Conclusion

SpringBoot’s conveniences hide many assumptions; proactively tuning defaults—connection pools, caching, logging, serialization, and thread management—prevents production incidents and improves system reliability.

Optimization
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

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.