VOOZH about

URL: https://www.javacodegeeks.com/2026/03/vector-api-at-eleven-incubations-why-this-api-takes-so-long-and-whats-blocking-it.html

⇱ Vector API at Eleven Incubations: Why This API Takes So Long and What's Blocking It - Java Code Geeks


JEP 529 ships in JDK 26 with no substantial changes since JDK 25. After five years and eleven rounds, the story behind the wait is actually a masterclass in JDK planning constraints — and in what happens when a good API design depends on language features that don’t exist yet.

1. Eleven Times and Counting

No API in the JDK’s modern history has spent as long in incubation as the Vector API. Ten versions. Eleven JEPs. Five calendar years. And counting — explicitly, deliberately, because the language it needs does not exist yet.

JEP 529, re-incubating the Vector API in JDK 26, was targeted by Mark Reinhold in October 2025, delivered in March 2026, and carries a note that has appeared in every incubation since JDK 16: “The Vector API will incubate until necessary features of Project Valhalla become available as preview features.” As InfoQ confirmed on JDK 26’s release day: no substantial implementation changes since JDK 25. Not because the Vector API team is slow, not because the SIMD hardware is unsupported, but because the API is deliberately waiting to be designed right.

This is a fascinating situation on multiple levels. The Vector API works today — you can use it right now on JDK 16 through 26 to write SIMD-accelerated Java code that genuinely outperforms scalar implementations on supported hardware. It is not broken. It is not experimental in its implementation. It is being held at the incubation stage because graduating it to preview would commit the JDK to an API shape that Valhalla will require it to abandon. And that trade-off — accept a worse API shape now vs wait for a better one — is the core tension the JDK team has been navigating for five years.

Understanding why leads directly into the deepest currents of ongoing JDK design: how value types, generics over primitives, and the identity model interact, and why all three need to arrive together for the Vector API to make sense at the language level.

2. What the Vector API Actually Does

Before examining the blocker, it is worth being precise about what the Vector API provides, because the level of capability it offers is genuinely impressive even in its current incubating form.

SIMD — Single Instruction, Multiple Data — is the hardware mechanism by which modern CPUs can apply a single operation to multiple data elements simultaneously. An AVX-512-equipped x86 processor can, in a single instruction, add sixteen 32-bit integers, multiply eight 64-bit floats, or XOR four 128-bit values. The performance difference between vectorised and scalar code on numerical workloads can be 4×, 8×, or 16× — the multiplicative factor being the vector width divided by the element size.

Java’s auto-vectoriser — the HotSpot JIT’s attempt to automatically recognise loops that could be vectorised — exists but is limited in what it can reliably detect. The Vector API gives developers explicit control: you write the vectorised operations directly, using an API that the JIT compiler recognises and lowers to the appropriate SIMD instructions on x64 (using AVX, AVX2, AVX-512) and AArch64 (using NEON and SVE). As the JEP states: vector computations that reliably compile at runtime to optimal vector instructions on supported CPU architectures, achieving performance superior to equivalent scalar computations.

Java — Vector API today (incubating, JDK 16–26)

// Requires --add-modules jdk.incubator.vector
import jdk.incubator.vector.*;

public class VectorSumExample {

 private static final VectorSpecies<Float> SPECIES =
 FloatVector.SPECIES_PREFERRED; // picks widest supported SIMD width

 public static float vectorisedDotProduct(float[] a, float[] b) {
 var acc = FloatVector.zero(SPECIES);
 int i = 0;

 // Main vectorised loop — processes SPECIES.length() floats per iteration
 for (; i < SPECIES.loopBound(a.length); i += SPECIES.length()) {
 var va = FloatVector.fromArray(SPECIES, a, i);
 var vb = FloatVector.fromArray(SPECIES, b, i);
 acc = va.fma(vb, acc); // fused multiply-add — one instruction
 }

 float result = acc.reduceLanes(VectorOperators.ADD);

 // Scalar tail — handles remainder elements not fitting a full vector
 for (; i < a.length; i++) {
 result += a[i] * b[i];
 }
 return result;
 }
}

This code works. It compiles. On a machine with AVX-512, SPECIES_PREFERRED resolves to 16 lanes of 32-bit float — sixteen multiply-add operations per iteration, in a single CPU instruction. The JIT recognises the API calls and emits the correct SIMD instructions. For numerical computing, signal processing, machine learning feature engineering, or cryptographic operations, this is genuinely transformative performance in pure Java.

The only catch is that --add-modules jdk.incubator.vector on every compiler and JVM invocation. And the implicit warning: this API is not stable. Its type signatures may change.

3. The Complete Incubation History

Ten rounds of incubation were delivered in JDK 16 through JDK 25, each carrying the Vector API forward. Not all rounds were equal — some brought substantial additions, others simply held the API stable while waiting for downstream dependencies to catch up. The full timeline reveals the pattern clearly.

Vector API incubation timeline — JDK 16 to JDK 26

👁 Image
Significant changes vs holding rounds across all eleven incubations. The shift from active development to holding pattern in JDK 22–26 reflects the Valhalla dependency reaching an explicit blocking stage. Source: OpenJDK JEP history.
JDKJEPReleaseSignificant changesStatus
JDK 16JEP 338Mar 2021First incubation — initial API surface, x64 only1st incubation
JDK 17JEP 414Sep 2021AArch64 support added; cross-lane operations expandedChanges
JDK 18JEP 417Mar 2022Further AArch64 operations; transcendental operations via SVML/SLEEFChanges
JDK 19JEP 426Sep 2022Alignment with structured access to memory (MemorySegment); performance improvementsChanges
JDK 20JEP 438Mar 2023Minor API refinements; continued memory segment alignmentMinor changes
JDK 21JEP 448Sep 2023Alignment updates; operations now work with MemorySegment GA API (FFM)Minor changes
JDK 22JEP 460Mar 2024No API changes — first explicit hold for ValhallaHold
JDK 23JEP 469Sep 2024No API changes — holding for ValhallaHold
JDK 24JEP 489Mar 2025No API changes — holding for ValhallaHold
JDK 25JEP 510Sep 2025No API changes — holding for ValhallaHold
JDK 26JEP 529Mar 2026No API changes — holding for Valhalla preview features11th · Active hold

4. The Actual Blocker: Why Valhalla Generics Matter

The JEP is admirably direct about what is blocking graduation. From the JEP itself: “The Vector API uses box types (e.g., Integer) as proxies for primitive types (e.g., int). This decision is forced by the current limitations of Java generics, which are hostile to primitive types. When Project Valhalla eventually introduces more capable generics then the current decision will seem awkward, and will likely need changing.”

This sentence contains the entire explanation, but it needs unpacking. Java generics, as they exist today, are erased at compile time and constrained at the type level to work only with reference types. You cannot write Vector<int> in Java today — the generic type parameter must be a reference type. So the Vector API uses the boxed equivalent: Vector<Integer> for a vector of 32-bit integers, Vector<Float> for a vector of 32-bit floats, Vector<Long> for 64-bit integers, and so on.

From an ergonomic standpoint, this is already slightly awkward — the types name boxed objects when what you are actually working with are primitive values packed into SIMD registers. But the deeper problem is what happens once Valhalla’s generic specialisation arrives. At that point, Vector<int> becomes a meaningful type — not a boxed type, but a genuine parameterisation over a primitive. The current API’s use of Vector<Integer> would then look not just awkward but wrong. Worse, it might need to coexist with a new Vector<int> form in a confusing way, or it would need to be changed in a way that breaks backwards compatibility for all existing Vector API code.

The precise Valhalla dependency: JEP 529 states the expected future explicitly: “We expect, further, to leverage Project Valhalla’s generic specialization of value classes so that instances of Vector<E> are value objects, where E is a primitive class such as int instead of its boxed class Integer. Subtypes of Vector<E> for specific types, such as IntVector, might not be required once we have generic specialization over primitive classes.” In other words: IntVectorFloatVectorLongVector — the current concrete subtypes — exist only because generic primitives don’t. Once they do, the entire type hierarchy of the Vector API simplifies.

5. The Boxing Problem in Concrete Terms

To understand why this matters in practice, consider what the boxing requirement costs. When you write VectorSpecies<Float>, the type parameter Float is a reference type — an object on the heap, with an object header and identity. At the SIMD register level, however, a 512-bit AVX-512 register holding sixteen single-precision floats contains no object headers. It contains sixteen packed 32-bit values, directly. The boxing is a pure type-system fiction that the JIT compiler has to see through entirely.

In practice, the JIT is good enough at this that you pay no boxing cost at runtime for the SIMD operations themselves. The compiler recognises the Vector API intrinsics and emits the appropriate SIMD instructions, discarding any object-oriented indirection. But the fiction creates real costs at the API design level: every method signature that could be cleaner with primitive type parameters is instead written with boxed ones. The distinction between IntVector and FloatVector — which in a world with generic primitives could simply be Vector<int> and Vector<float> — is currently encoded through explicit subclasses, multiplying the API surface.

Java — current API shape vs future Valhalla shape (illustrative)

// CURRENT: boxed type parameter, explicit subtypes per primitive
VectorSpecies<Float> floatSpecies = FloatVector.SPECIES_256;
VectorSpecies<Integer> intSpecies = IntVector.SPECIES_256;
VectorSpecies<Long> longSpecies = LongVector.SPECIES_256;

FloatVector fv = FloatVector.fromArray(floatSpecies, floatData, 0);
IntVector iv = IntVector.fromArray(intSpecies, intData, 0);

// FUTURE (after Valhalla generic specialisation — not available yet):
// E is a primitive class — no boxing, no IntVector/FloatVector subclasses needed
VectorSpecies<float> floatSpecies = Vector.species(float.class, 256);
Vector<float> fv = Vector.fromArray(floatSpecies, floatData, 0);
// Same generic type, no distinct subclasses, no boxed proxy

6. Value Classes: The Other Half of the Dependency

Generic specialisation over primitives is not the only Valhalla dependency. The JEP is equally explicit about value classes. From JEP 529: “We expect ultimately to declare vector classes as value classes. For ongoing efforts to align the Vector API with Valhalla, see the lworld+vector branch of Project Valhalla’s development repository.”

A value class, in Valhalla’s model, is a class whose instances lack object identity. Two instances of a value class are equal if and only if their fields are equal — there is no concept of “the same object” that is distinct from “an object with the same value.” This is semantically correct for vectors: a vector of sixteen floats containing [1.0, 2.0, ..., 16.0] is simply that vector — its identity as a heap object is irrelevant. Carrying object identity overhead for vectors is both wasteful and conceptually wrong.

Currently, Vector classes are declared as value-based classes — a weaker advisory designation that says “treat these as if they had value semantics, but we cannot enforce it yet.” JEP 401 (Value Classes and Objects), which is targeted for preview in JDK 26 or shortly after, is the JEP that will make value classes a formal language feature. Once it ships as a preview, the Vector API team can begin adapting the Vector classes to be proper value classes — and at that point, the API can leave incubation and enter preview itself.

JEP 401 is the direct predecessor: JEP 401 (Value Classes and Objects) has early-access builds implementing value classes with preview features in early-access builds of JDK 26. The anticipated delivery is now within the next 1–2 releases. When it ships as a preview, the Vector API can be adapted to declare Vector<E> and its subtypes as value classes — and graduation from incubation to preview becomes possible. JEP 500 (Prepare to Make Final Mean Final), also in JDK 26, is a preparatory step for the object model changes Valhalla requires.

7. What JEP 529 Actually Changed (Or Didn’t)

The JEP 529 text is explicit and brief on this point: “We here propose to re-incubate the Vector API in JDK 26 with no API changes and no substantial implementation changes relative to JDK 25.” This is an intentional and reasoned decision, not a failure to ship.

The reason no changes were made is the same reason the API is still incubating: making changes now would be changes to a shape that is about to change again when Valhalla lands. Every method signature refined today is a signature that might need to change again — and with it, every piece of user code that adopted the incubating API. The JDK team’s calculation is correct: stability during the hold period is more valuable than incremental refinement of an API that is known to be structurally wrong at the type-parameter level.

However, “no substantial implementation changes” does not mean the implementation stood still entirely. The JIT compiler’s handling of Vector API intrinsics continues to improve across JDK releases independently of the API surface. The code you write in JDK 26 performs better than the same code in JDK 16 not because the API changed, but because the HotSpot compiler improved its lowering of Vector API operations to SIMD instructions. Float16 support is under active development on the vectorIntrinsics+fp16 branch of Project Panama. RISC-V support, contributed by the community, has been progressing.

8. JEP 500: The Quiet Signal That Valhalla Is Closer

The most revealing signal in JDK 26 for Vector API watchers is not JEP 529 itself — it is JEP 500: Prepare to Make Final Mean Final. This JEP changes the semantics of the final keyword in ways that are preparatory for Valhalla’s object model.

Currently, the final keyword on a field provides a write-once guarantee that the compiler can use for optimisation, but does not prevent identity-sensitive operations. Valhalla’s value classes require a stricter interpretation: a field that is final in a value object is final in an absolute sense — there is no identity through which it could be mutated via reflection tricks or unsafe operations. JEP 500 begins this tightening: it introduces warnings and eventual errors for code that attempts to mutate final fields via reflection, setting up the platform for value classes to make their stricter guarantees credible.

As Hanno Embregts observed in his Java 26 analysis: “My hope is that the first JEPs out of Project Valhalla will be announced later this year. That hope is fuelled by some of Java 26’s changes as they feel like appropriate preparation steps for the first Valhalla features — this is especially true for JEPs 500 and 529.” The combination of JEP 500 (fixing the preconditions for value classes) and JEP 529 (holding the Vector API ready to adopt them) is the JDK doing its preparation work in public.

9. Why the Incubation Model Exists and What It Gets Right

The Vector API’s eleven-incubation journey is an extreme case of a process that the JDK uses deliberately. As the JavaCodeGeeks analysis of Java’s future trajectory notes: the six-month model allows features to mature through multiple preview rounds across releases without blocking other improvements. This patience-enabling structure proves crucial for complex initiatives like Valhalla, which require extensive real-world testing before stabilisation.

The incubation stage — formally defined in JEP 11 — exists specifically for APIs that need real-world feedback before the JDK commits to them permanently. An incubating API lives in the jdk.incubator.* module namespace, requires an explicit --add-modules flag to use, is not part of the Java SE standard (so it cannot be relied upon by libraries with wide reach), and carries an explicit promise that it may change in future versions. Crucially, it can ship in a release even when the team knows the API is structurally imperfect — because getting real-world usage data from the imperfect version is more valuable than shipping nothing while waiting for perfection.

What the incubation constraint protects you from: The jdk.incubator.vector module requirement is not bureaucratic friction. It is a deliberate signal: this API is in the jdk.incubator namespace, meaning no library on Maven Central should depend on it transitively. If Spring, Guava, or Jackson depended on an incubating API, millions of applications would break each time that API changed. The module requirement keeps incubating APIs out of the library ecosystem’s transitive dependency graph until the API is stable enough to commit to permanently.

10. Using the Vector API Today: Is It Worth It?

Given eleven incubations and an explicitly unstable API contract, the practical question for a working Java engineer is: should you use the Vector API in production code today?

The answer is a conditional yes — and the condition is domain-specific. For performance-critical numerical, cryptographic, or data-processing code where the team is prepared to handle API changes at major JDK boundaries, the Vector API is the right tool. The performance gains are real: a hand-vectorised dot product using the Vector API with AVX-512 hardware is legitimately 10–16× faster than the scalar equivalent. No amount of scalar optimisation closes that gap. Furthermore, the JIT does actually recognise and compile the API to SIMD instructions reliably in JDK 21+.

For general application code — web services, database access layers, business logic — the Vector API is not relevant. Auto-vectorisation handles the numerical portions of typical application code adequately, and the module flag overhead and API instability cost are not justified by any realistic performance gain.

Use caseVector API today?Rationale
ML inference / embedding computationYesDot products, activations, matrix operations — exactly the workloads SIMD dominates. Real-world 4–16× gains documented.
Cryptographic primitives (AES, SHA)YesBitwise and arithmetic operations on fixed-width data — ideal Vector API workload. JDK’s own crypto uses intrinsics derived from this approach.
Signal/image processing (FFT, convolution)YesComplex number arithmetic, bulk float operations — a primary design target of the API.
SIMD-accelerated text search / parsingConditionalViable, but the API is not optimised for byte-level operations the way SWAR techniques are. Measure carefully.
General web / business logicNoNot applicable. Module flag overhead, API instability, and no meaningful performance benefit for this workload class.
Library code (open-source, Maven)NoAn incubating API must not appear in transitive dependencies. Wait for graduation before including in any library with external users.

11. When Does It Graduate?

The graduation condition is precisely stated in every Vector API JEP: “The Vector API will incubate until necessary features of Project Valhalla become available as preview features. At that time, we will adapt the Vector API and its implementation to use them and then promote the Vector API from incubation to preview.”

So the question reduces to: when does Valhalla ship its relevant preview features? The most optimistic reading of the current signals — JEP 401 in early-access builds, JEP 500 in JDK 26, active work on the lworld+vector branch — points to JDK 27 (September 2026) or JDK 28 (March 2027) as the likely window for Valhalla value classes to enter preview. JEP 401 has been described by InfoQ as targeted for “JDK 27 at this time,” while acknowledging that draft JEPs can change. Even after JEP 401 previews, the Vector API team will need an adaptation period — likely one additional JDK cycle — to retrofit the API to use value classes and primitive generics before it can enter its own preview.

Realistically: the Vector API is unlikely to be in preview before JDK 28 (March 2027) and may not be GA before JDK 30 or 31 (2027–2028). That is twelve to fourteen incubations in total. It will also be, when it arrives, one of the most carefully designed and correctly shaped APIs the JDK has ever shipped — because it will have been held until the language could support it properly.

The right way to read this story: The eleven incubations are not a failure of the Java release process — they are evidence that it is working as designed. The alternative would have been to graduate the Vector API with Vector<Integer> and explicit IntVector/FloatVector subtypes, permanently committing the JDK to an API shape that everyone involved knows is a workaround for missing language features. The incubation model gives the team the ability to say, publicly and honestly: this API exists, you can use it, and we reserve the right to make it correct when the language catches up.

12. What We Have Learned

The Vector API’s eleven-incubation journey is the most instructive case study in the modern JDK’s development model. Here is the distilled picture:

  • JEP 529 re-incubates the Vector API in JDK 26 with no API changes and no substantial implementation changes since JDK 25. This is deliberate, not a shipping failure.
  • The Vector API works today for SIMD-accelerated numerical, cryptographic, and signal-processing code on x64 (AVX/AVX-512) and AArch64 (NEON/SVE). The performance gains — 4–16× vs scalar — are real. The instability cost is an API signature change risk at major JDK boundaries.
  • The blocking dependency is dual: Project Valhalla’s generic specialisation over primitive types (so Vector<int> becomes legal), and value classes (so Vector instances can be declared as lacking object identity). Both are prerequisites for the API to have the correct shape permanently.
  • Current awkwardness: boxed type parameters (Vector<Float> instead of Vector<float>) and explicit subclasses (IntVectorFloatVector) exist solely because Java generics cannot express primitive type parameters today. Once Valhalla lands, these will be unnecessary.
  • JEP 401 (Value Classes and Objects) is the direct predecessor. Early-access builds exist. JEP 500 in JDK 26 (Prepare to Make Final Mean Final) is a preparatory tightening of the object model ahead of value class support.
  • Graduation timeline: realistically JDK 28–30 (2027–2028), contingent on Valhalla value classes entering preview in JDK 27. Twelve to fourteen total incubations is a plausible final count.
  • The incubation model is working exactly as designed. Graduating a structurally wrong API permanently — to avoid an eleventh incubation — would have been the mistake. The wait is the right call.
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

Thank you!

We will contact you soon.

👁 Photo of Eleftheria Drosopoulou
Eleftheria Drosopoulou
March 27th, 2026Last Updated: March 20th, 2026
0 410 14 minutes read

Eleftheria Drosopoulou

Eleftheria is an Experienced Business Analyst with a robust background in the computer software industry. Proficient in Computer Software Training, Digital Marketing, HTML Scripting, and Microsoft Office, they bring a wealth of technical skills to the table. Additionally, she has a love for writing articles on various tech subjects, showcasing a talent for translating complex concepts into accessible content.
Subscribe

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button
Close
wpDiscuz