Sitemap
Ankit Kathait

Ankit Kathait

Backend sorcerer weaving digital realms. Turning caffeine into code and bugs into features. Let's debug the world, one line at a time.

Virtual Threads in Java

3 min readOct 5, 2026

--

Introduction

Virtual threads are software based threads introduced as a preview in Java 19(2022) and finalized as part of Java 21(2023). Unlike a core based thread which map to 1:1 threads on the OS, these are software based threads managed by JVM on top of the OS based threads.

Differences between “normal/platform” and Virtual threads:

  1. Virtual threads are managed by JVM on top of OS threads. Threads are tied to OS threads.
  2. Because virtual threads are managed by JVM, their count can be much higher than the count of actual OS threads.
  3. Virtual threads are “cheaper” to manage as compared to virtual threads. Platform threads reserve stack and memory upfront even though they might not use it. Generally they reserve upto 1MB up front. Virtual threads on the other hand, work with the JVM stack memory and increase the memory as the thread requires it.
  4. Platform threads need to make a kernel syscall to set up the stack, register it with the OS scheduler and do other associated tasks on the OS and kernel level. This can take about 100–300 μs per thread. Virtual threads are basically just a java object being allocated on the heap memory and JVM’s scheduler, making it much faster. Virtual threads can be up and ready to use in about 10 μs, making then about 10–30x faster than a platform thread

When to use each type of thread:

While the differences above make it seem it like virtual threads is an “upgrade” over the platform thread, but it is not such a case. Platform threads still have their own use case as well.

When to use platform thread:

Any tasks that make the CPU actually busy are a better use case for platform threads. While virtual threads might be just as good, but they do not increase the number of CPU cycles. Also too much switching by using too many virtual threads make just increase the cost. Examples:

  1. CPU based processing like image/video editing, encoding, ML inference etc.
  2. Heavy native/JNI code
  3. Long running synchronized blocks

Any process which might be dependent on the thread identity(Thread.currentThread()) would require to use platform threads.

Get Ankit Kathait’s stories in your inbox

Join Medium for free to get updates from this writer.

When to use virtual threads:

  1. Tasks which have a lot of CPU idle like DB calls, API calls, reading from disk, socket calls etc
  2. API/webservices which need to handle millions of requests per minute but still need to handle blocking calls like DB/API etc.
  3. Simple synchronous code or short lived tasks

Rule of thumb: if your application never has ~10,000+ concurrent threads, virtual threads likely won’t give you a meaningful benefit.

Efficiency comparison of platform threads vs virtual threads:

Code being used to do the comparison:

public static void main(String[] args) throws Exception {
int count = 1_000_000;

// --- Platform Threads ---
long start = System.nanoTime();
for (int i = 0; i < count; i++) {
Thread t = new Thread(() -> {});
t.start();
t.join();
}
long platformTime = System.nanoTime() - start;
System.out.printf("Platform threads: %,d threads in %.1f ms%n",
count, platformTime / 1_000_000.0);

// --- Virtual Threads ---
start = System.nanoTime();
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < count; i++) {
Future<?> f = executor.submit(() -> {});
f.get();
}
}
long virtualTime = System.nanoTime() - start;
System.out.printf("Virtual threads: %,d threads in %.1f ms%n",
count, virtualTime / 1_000_000.0);

System.out.printf("Speedup: %.1fx%n", (double) platformTime / virtualTime);
}

The results will vary from machine to machine. Here are the results for my machine:

Platform threads: 1,000,000 threads in 252142.8 ms
Virtual threads: 1,000,000 threads in 15532.7 ms
Speedup: 16.2x

Resources:

Oracle docs
Dev.java
GeeksforGeeks

--

--

Ankit Kathait
Ankit Kathait

Backend sorcerer weaving digital realms. Turning caffeine into code and bugs into features. Let's debug the world, one line at a time.