How Many Requests Can a Default SpringBoot App Handle? Tomcat vs Undertow Explained
This article walks through an interview question about the maximum concurrent requests a SpringBoot project can handle, builds a minimal demo, measures Tomcat and Undertow thread‑pool limits, explains the underlying thread‑pool mechanics, and offers practical tips for answering such questions in interviews.
Hello, I'm Su San. This article explores a common interview question: how many requests can a SpringBoot project handle simultaneously?
A SpringBoot project with default settings, what is the maximum number of concurrent requests?
Demo
A minimal SpringBoot demo (version 2.7.13) is created with only two dependencies and a single controller:
@Slf4j
@RestController
public class TestController {
@GetMapping("/getTest")
public void getTest(int num) throws Exception {
log.info("{} received request:num={}", Thread.currentThread().getName(), num);
TimeUnit.HOURS.sleep(1);
}
}The application.properties file is left empty.
To test the limit, a simple loop spawns many threads that call the endpoint:
public class MainTest {
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
int finalI = i;
new Thread(() -> {
HttpUtil.get("127.0.0.1:8080/getTest?num=" + finalI);
}).start();
}
Thread.yield();
}
}Running the demo and counting the log lines that contain the keyword "received request" shows that, with default Tomcat, 200 requests are processed concurrently.
How the Answer Is Derived
Tomcat, not SpringBoot, manages the request threads. By inspecting a thread dump you can see that Tomcat uses a ThreadPoolExecutor with corePoolSize = 10 and maximumPoolSize = 200, while the work queue length is effectively unlimited (Integer.MAX_VALUE). Tomcat’s pool differs from the JDK pool: after the core threads are saturated it immediately creates threads up to the maximum size, bypassing the queue.
The relevant code in Tomcat’s TaskQueue#offer method decides whether to enqueue a task or trigger the creation of a non‑core thread based on the current pool size and maximum size.
Impact of Configuration
Changing server.tomcat.max-connections to a value lower than the default (8192) limits the number of concurrent connections; setting it to 10 reduces the processed requests to 10.
Switching to Undertow
Replacing Tomcat with Undertow (by changing Maven dependencies) changes the default thread‑pool parameters. In the author’s environment (6 CPU cores) Undertow creates 48 worker threads (coreSize = maxSize = 48) with an unlimited queue. This explains why only 48 requests were handled in the same test.
Undertow derives the worker thread count from cpuCount * 8, where cpuCount is the number of CPU cores.
Effect of @Async
Adding the @Async annotation introduces a separate thread pool whose default core size is 8, reducing the concurrent request handling to 8.
Interview Tips
When faced with vague interview questions, first clarify the environment (e.g., which web container is used) and then explain the relevant thread‑pool settings. Mention that SpringBoot defaults to Tomcat with core = 10, max = 200, and an unbounded queue, so the practical concurrent limit is 200 unless other parameters (like max-connections) are changed.
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.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.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.
