Spring Boot API Aggregation: Sequential, CompletableFuture, and Virtual Thread Structured Concurrency Performance
The article benchmarks three Spring Boot aggregation approaches—sequential calls, CompletableFuture parallelism, and virtual‑thread structured concurrency—using JMeter on a Spring Boot 3.5.0 service, showing that CompletableFuture delivers the lowest latency, structured concurrency offers better reliability, and sequential execution performs the worst.
Environment
Spring Boot 3.5.0
1. Sequential calls
private final UserRepository ur;
public Map<String, Object> complexQuerySequential() {
String name = "费青汉";
List<User> users = this.ur.findByName(name);
Long count = this.ur.countUser();
User user = this.ur.findById(3599999).get();
return Map.of("list", users, "count", count, "user", user);
}This method performs three blocking database queries one after another, resulting in a longer overall response time.
2. CompletableFuture parallelism
public Map<String, Object> complexQueryCompletableFuture() {
String name = "费青汉";
Map<String, Object> ret = new HashMap<>();
CompletableFuture.allOf(
CompletableFuture.supplyAsync(() -> this.ur.findByName(name))
.thenAccept(val -> ret.put("list", val)),
CompletableFuture.supplyAsync(() -> this.ur.countUser())
.thenAccept(val -> ret.put("count", val)),
CompletableFuture.supplyAsync(() -> this.ur.findById(3599999).get())
.thenAccept(val -> ret.put("user", val))
).join();
return ret;
}All three queries are launched asynchronously with supplyAsync; thenAccept stores each result in a shared map, and allOf().join() waits for completion.
3. Virtual‑thread structured concurrency
public Map<String, Object> complexQueryVirtualThreadStructuredConcurrent() {
String name = "费青汉";
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
var listFuture = scope.fork(() -> this.ur.findByName(name));
Subtask<Long> countFuture = scope.fork(() -> this.ur.countUser());
Subtask<Optional<User>> userFuture = scope.fork(() -> this.ur.findById(3599999));
scope.join();
scope.throwIfFailed();
return Map.of(
"list", listFuture.get(),
"count", countFuture.get(),
"user", userFuture.get()
);
} catch (Exception e) {
throw new RuntimeException(e);
}
}This version uses virtual threads and StructuredTaskScope to fork the three queries, joins them, and propagates any failure. Compared with CompletableFuture, it simplifies lifecycle management and reduces the risk of resource leaks while keeping the code readable.
Note: Replacing the virtual‑thread factory with Thread.ofPlatform().factory() creates unlimited platform threads, which can eventually cause OOM.
4. Test setup
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) { this.userService = userService; }
@GetMapping("/sequential")
public ResponseEntity<?> complexQuerySequential() {
return ResponseEntity.ok(this.userService.complexQuerySequential());
}
@GetMapping("/completablefuture")
public ResponseEntity<?> complexQueryCompletableFuture() {
return ResponseEntity.ok(this.userService.complexQueryCompletableFuture());
}
@GetMapping("/vt")
public ResponseEntity<?> complexQueryVirtualThreadStructuredConcurrent() {
return ResponseEntity.ok(this.userService.complexQueryVirtualThreadStructuredConcurrent());
}
}The three endpoints are load‑tested with JMeter.
5. Results
CompletableFuture delivers the best performance : lowest response time and highest throughput in the benchmark.
Structured concurrency offers higher reliability : slightly slower than CompletableFuture but simplifies task management and error handling.
Sequential calls have the lowest efficiency : suitable only for low‑traffic or non‑real‑time scenarios.
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.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
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.
