Understanding Spring Boot's Request Handling Limits Through Tomcat Configuration
This article explains how Spring Boot's request capacity is determined by Tomcat's configuration parameters, demonstrates the impact of min‑spare, max threads, max‑connections, and accept‑count through a small example, and discusses concurrency pitfalls caused by singleton beans.
Spring Boot runs on an embedded Tomcat container, so the number of requests it can handle is essentially limited by Tomcat's configuration.
The default Tomcat settings are defined in spring-configuration-metadata.json and mapped to the class org.springframework.boot.autoconfigure.web.ServerProperties.
Four key parameters affect request handling:
server.tomcat.threads.min-spare : minimum number of worker threads (default 10).
server.tomcat.threads.max : maximum number of worker threads (default 200).
server.tomcat.max-connections : maximum number of simultaneous connections (default 8192).
server.tomcat.accept-count : length of the waiting queue (default 100).
Using a restaurant analogy, a request is a customer, min‑spare threads are permanent chefs, max threads are total chefs (permanent + temporary), max‑connections are seats, and accept‑count is the number of stools at the entrance.
The effective maximum number of requests Spring Boot can process equals max-connections + accept-count; any excess requests are dropped.
Example configuration (application.yml):
server:
tomcat:
threads:
# minimum threads
min-spare: 10
# maximum threads
max: 15
# maximum connections
max-connections: 30
# maximum waiting count
accept-count: 10Simple controller:
@GetMapping("/test")
public Response test1(HttpServletRequest request) throws Exception {
log.info("ip:{}, thread:{}", request.getRemoteAddr(), Thread.currentThread().getName());
Thread.sleep(500);
return Response.buildSuccess();
}Running a test with 100 concurrent requests (using Apifox) shows that 60 requests are discarded because max-connections + accept-count = 40. With a maximum of 15 threads, 25 requests wait, then are processed in three batches of 15, 15, and 10.
Summary: If concurrent requests are below server.tomcat.threads.max, they are handled immediately; excess requests wait up to accept-count; requests beyond max-connections + accept-count are dropped.
Extended discussion: concurrency issues
In Spring, beans are singleton by default, so shared mutable state (e.g., a global cookSum variable) can lead to race conditions where multiple threads read the same value, increment, and write back, resulting in lost updates. The following code illustrates the problem:
private int cookSum = 0;
@GetMapping("/test")
public Response test1(HttpServletRequest request) throws Exception {
// simulate cooking
cookSum += 1;
log.info("cooked {} dishes", cookSum);
Thread.sleep(500);
return Response.buildSuccess();
}Resolving such issues requires proper synchronization (e.g., locking), which is beyond the scope of this article.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
