What this prompt does
This prompt guides a migration of a Spring Boot application from platform threads to Java 21 virtual threads, starting from your [current_setup]. It audits thread usage to find blocking operations ([blocking_ops]), configures Spring Boot [spring_version] to handle requests on virtual threads, migrates @Async methods to a virtual-thread executor, removes pool sizing where it no longer applies, identifies and fixes pinning from synchronized blocks and native calls, handles ThreadLocal usage with ScopedValues, resizes the [db_pool] connection pool, benchmarks virtual threads against your current [current_throughput], applies structured concurrency for [concurrent_tasks], and monitors behavior with JFR events — listing gotchas and anti-patterns.
The structure works because a Loom migration is cheap when a service is thread-starved, but pinning and connection-pool exhaustion are exactly where it quietly breaks. Auditing [blocking_ops] and the [db_pool] first means those traps are addressed before they cause regressions under load. Replacing ThreadLocal usage with ScopedValues is a related cleanup, since context that rode along on a bounded thread pool behaves differently once thousands of virtual threads exist, and the benchmark against [current_throughput] is what proves the migration actually paid off.
When to use it
- A Spring Boot service is thread-starved under load and you want the cheapest concurrency win.
- You have many blocking I/O operations (
[blocking_ops]) that virtual threads can scale cheaply. - You are on Spring Boot
[spring_version]and Java 21 and want request handling on virtual threads. - You need to find and fix pinning from synchronized blocks or native calls before it bites.
- You want to right-size
[db_pool]because virtual threads can exhaust a connection pool. - You want a before/after benchmark against
[current_throughput]to prove the change helped.
Example output
Expect a migration plan with code: configuration to enable virtual threads for requests and @Async, a list of pinning sites with fixes, ScopedValue replacements for problematic ThreadLocals, revised [db_pool] sizing guidance, a benchmark comparison against [current_throughput], a StructuredTaskScope implementation for [concurrent_tasks], JFR monitoring setup, and a gotchas section. It is a sequenced playbook rather than a single config change.
Pro tips
- Describe
[current_setup]accurately (server, pool size, async style) so the migration starts from your real configuration. - List
[blocking_ops]honestly, since virtual threads help blocking I/O most and CPU-bound work least. - Audit pinning before flipping the switch; a synchronized block around a blocking call pins a carrier thread and erases the benefit.
- Re-examine
[db_pool]sizing carefully, because virtual threads can spawn far more concurrent queries than platform threads did. - Use the benchmark against
[current_throughput]to confirm a real gain rather than assuming virtual threads always help. - Iterate by asking it to convert one specific
@Asyncflow and show the StructuredTaskScope version for[concurrent_tasks].