A demo Spring Boot project exploring the use of 'Virtual threads' in Java 21 to handle high-concurrency REST endpoints. This project benchmarks the performance differences between traditional servlet threads, platform threads, and virtual threads, particularly in data-fetching endpoints powered by Spring Data JPA and MySQL.
Virtual threads are a major feature introduced in Java 21 as part of Project Loom. Unlike traditional platform threads, which are managed by the OS, virtual threads are managed by the JVM and are much lighter and more scalable.
- Thousands of virtual threads can run concurrently with minimal memory footprint.
- Ideal for I/O-bound applications such as web servers or microservices.
- Virtual threads help reduce thread contention and simplify asynchronous programming without complex callback logic or
CompletableFuture
chains.
🔗 Read more: Java Virtual Threads – Official Docs
-
Clone the project:
git clone https://github.com/your-username/springboot-virtual-thread-analysis.git cd springboot-virtual-thread-analysis
-
Make sure you are using Java 21+ , Maven 3.8+ and MySQL running with database named as 'test'
-
Run the application:
mvn spring-boot:run
-
Access Swagger UI:
-
Open your browser and go to: 👉 http://localhost:9090/swagger-ui/index.html
-
-
Use the
/reports/{region}
endpoints by entering a region like"India"
in Swagger.
The application provides 3 different endpoints that internally execute the same logic but differ in the threading model used:
/reports/India
– Traditional (Baseline)/reports/platform/India
– Uses platform threads explicitly/reports/virtual/India
– Uses virtual threads (viaExecutors.newVirtualThreadPerTaskExecutor()
)
We used ApacheBench (ab.exe
) to benchmark each endpoint under 1000 requests with a concurrency level of 50.
Metric | /reports/India (Baseline) |
/platform/India (Platform Thread) |
/virtual/India (Virtual Thread) |
---|---|---|---|
Total Requests | 1000 | 1000 | 1000 |
Concurrency Level | 50 | 50 | 50 |
Test Duration (sec) | 0.680 | 0.572 | 0.362 |
Requests/sec | 1470.81 | 1746.88 | 2762.99 |
Mean Time/request (ms) | 33.995 | 28.622 | 18.096 |
Time/request per thread (ms) | 0.680 | 0.572 | 0.362 |
Transfer Rate (KB/s) | 328.92 | 406.01 | 639.48 |
Median Latency (ms) | 31 | 26 | 16 |
95th Percentile Latency (ms) | 55 | 49 | 30 |
Max Latency (ms) | 140 | 101 | 84 |
📌 Conclusion: Virtual threads significantly outperform both baseline and platform threads in terms of throughput and latency, demonstrating lower response times and higher request handling capacity under the same load.
- Java 21 (Virtual Threads)
- Spring Boot 3.5.x
- Spring Web & JPA
- MySQL
- ApacheBench for load testing
- Lombok
- Swagger (OpenAPI 3)
- Java Loom (OpenJDK)
- Spring Boot Team
- Apache HTTP Server Project (ab tool)