In-process similarity search and durable persistence, built on the JDK Vector API for SIMD distance kernels. No service to deploy, no network hop, no serialization boundary.
try (var collection = VectorCollection.builder()
.dimension(384)
.metric(SimilarityFunction.COSINE)
.indexType(IndexType.HNSW)
.build()) {
collection.add("a", embedding1, "hello world")
.add("b", embedding2, "goodbye world")
.commit();
SearchResult result = collection.search(
SearchRequest.builder(query, 5).build());
}
VectorStore store = JavaVectorsVectorStore
.builder(embeddingModel, collection)
.commitAfterAdd(true)
.build();
store.add(List.of(new Document("hello world")));
List<Document> hits = store.similaritySearch(
SearchRequest.builder().query("hello").topK(5).build());
EmbeddingStore<TextSegment> store =
JavaVectorsEmbeddingStore.builder(collection).build();
store.add(model.embed(segment).content(), segment);
var matches = store.search(EmbeddingSearchRequest.builder()
.queryEmbedding(model.embed("hello").content())
.maxResults(5)
.build());
Bring your own embeddings — one dependency and you're indexing in-process, no service to run.
Add the dependency
implementation("com.integrallis:vectors:0.1.20")
Requires JDK 25 · run with --add-modules jdk.incubator.vector
SimpleVectorStore is Spring AI's in-memory reference VectorStore:
it holds every vector in a map and scans the whole set on each query. Vectors is a drop-in
replacement that swaps that linear scan for a real index, adds quantization, and persists to
disk — while staying in-process. Only the construction changes; your call sites don't.
save() / load() to a fileRecall, throughput, and footprint depend on your corpus, hardware, and index settings — measure on your data. See the migration guide →
Vectors runs in-process. You create a collection, add documents, and search — all inside the JVM.
VectorCollection.builder()
.dimension(384)
.metric(COSINE)
.indexType(HNSW)
.build()
One builder unifies every index and quantizer behind a single API. Vectors are stored off-heap via MemorySegment, so large collections don't pressure the GC.
collection.add("a", vec, "hello")
.add("b", vec, "bye")
.commit();
collection.search(SearchRequest.builder(query, 10).build());
Commits are atomic and generation-based; the memory-mapped store recovers on restart, with tombstone deletes and background compaction.
The whole engine lives in your application process. There is no separate database to run, no client/server protocol, and nothing crossing a serialization boundary between your code and the index — just method calls on a JVM object.
Dot product, L2, and cosine vectorized with the Java Vector API (jdk.incubator.vector), with a pure-scalar fallback.
FLAT (exact), HNSW, Vamana / DiskANN, IVF_FLAT, and IVF_PQ — pick recall vs. speed vs. footprint per collection.
Scalar (SQ8/SQ4), product (PQ), binary (BQ/BBQ), RaBitQ, NVQ, and TurboQuant — shrink footprint, keep recall.
Memory-mapped storage with atomic, generation-based commits, crash recovery, tombstone deletes, and background compaction.
Spring AI VectorStore, LangChain4j EmbeddingStore, a Spring Boot starter, semantic caching, and routing.
Record Spring AI and LangChain4j chat, streaming, tool-call, and embedding responses once; replay signed cassettes offline in JUnit 5 or TestNG.