Why your Java 21 Virtual Threads might freeze under load (and how to spot pinning)

1 4
calendar_today agoschedule1 min read

A lot of teams migrated to Java 21 and flipped spring.threads.virtual.enabled=true, expecting instant scaling without the reactive boilerplate.

And for basic I/O, it works great. But once high concurrency hits, some services start seeing unexplained HTTP timeouts and latency spikes, even though CPU and memory metrics look totally calm.

The culprit is usually Carrier Thread Pinning.

Project Loom mounts virtual threads onto underlying OS platform threads (Carrier Threads, managed by an internal ForkJoinPool). When a virtual thread hits a blocking network call, Loom unmounts it so the carrier can pick up other work.

Where it breaks: If a virtual thread enters a synchronized block or method and blocks inside on I/O, the JVM cannot unmount it. The virtual thread stays "pinned" to its carrier thread. If your server has 8 cores, 8 pinned threads waiting on slow external APIs will freeze your entire carrier pool—even if you have 50,000 other virtual threads ready to run.

Quick mitigation:

Replace synchronized with ReentrantLock around any blocking I/O (j.u.c primitives support clean unmounting).

Test locally with -Djdk.tracePinnedThreads=short to dump offending methods to stdout.

Keep an eye on third-party JDBC drivers and legacy SDKs that still use monitor locks on socket reads.

I wrote an open-source diagnostics tool and Spring Boot Actuator endpoint to track pinning ratios and pool saturation in real time (LoomDoctor), and put together an interactive simulator if you want to test how carrier starvation happens under load: https://frodygr.github.io/playground/#loomdoctor

Have you hit carrier pinning in your Java 21 deployments yet? How did your team catch it?

2 Comments

0 votes
0
🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelski - Mar 19

Beyond the Crisis: Why Engineering Your Personal Health Baseline Matters

Huifer - Jan 24

Why “Building in Public” Is Hollowing Out Your Developer Career

Karol Modelski - Jun 18

Your Tech Stack Isn’t Your Ceiling. Your Story Is

Karol Modelski - Apr 9

Spring Boot File Upload Performance: Why Your API Gets Slow Under Load (And How to Fix It)

buildbasekit - May 20
chevron_left
144 Points5 Badges
1Posts
1Comments
2Connections

Related Jobs

View all jobs →

Commenters (This Week)

8 comments
2 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!