Do virtual threads make one request per thread practical again?

November 13, 2026 5 answers
Asked by Nulby.9

Java 21 virtual threads look like a simpler way to handle lots of requests that spend time waiting on I/O. Are they a straightforward replacement for platform thread pools, or are there catches for backend services?

Answers

Tovrick

For an I/O-heavy service, they can make that model practical without forcing every operation into a reactive pipeline. You can keep ordinary blocking code while having many requests waiting at once, with much less thread overhead than platform threads.

That does not make each request faster, though. Database queries and HTTP calls still take as long as they take. The benefit is being able to keep more waiting operations in flight without dedicating an operating system thread to each one.

Reply to this answer
Heddle.4

Watch the limits. A small platform thread pool may have been quietly limiting how many requests could reach a database or external API at once. Swap it for virtual threads and you can expose those dependencies to a lot more concurrency.

Use limits that match the actual resource, such as a semaphore around a downstream call, and account for connection pools and rate limits. A thread pool size and a downstream concurrency limit are different things, even if they used to produce similar behavior.

_quietly_undecided:

Retries need care here too. They can add more traffic to a dependency that is already struggling.

Reply to this answer
k205+wrreq_8

Virtual threads are not extra CPU cores. If an endpoint spends most of its time doing computation rather than waiting, creating more threads will not give it unlimited throughput. Check the workload before assuming the change will help.

Reply to this answer
mildly_freestanding

Library behavior matters too. In Java 21, a virtual thread can pin its carrier thread in some situations, including blocking while inside a synchronized block or method. Enough of that can hurt concurrency, so check the libraries and endpoints you depend on rather than assuming all blocking is equally cheap.

Test representative traffic, including the expensive endpoints. An endpoint that does substantial CPU work or uses a problematic library can change the performance picture quite a bit.

Reply to this answer
w418~baud_7

They are a good reason to reconsider whether you need a reactive framework for a service that mostly waits on I/O. Straightforward blocking code can be easier to follow and debug. Reactive tools still have their uses, so I would not treat this as a reason to rewrite everything automatically.

Reply to this answer

Add your answer

Answers are reviewed before publication.

Related Discussions