Vector Sets in Valkey and Redis: A Java Developer's Guide
AI search has fundamentally changed enterprise applications, both in how developers write code and how end users interact with these systems. If your Java development team now includes semantic search, recommendation engines, or retrieval-augmented generation (RAG) functionality in your apps, your databases have also been transformed. AI has turned nearly every traditional database into a vector database. For many teams, this means maintaining a separate vector store to handle this new class of data.
However, Java teams that already use the in-memory data stores Valkey and Redis have a better option. The introduction of the Redis vector sets data type in Redis 8, combined with Redisson's RVectorSet object, makes managing vector sets as easy as working with any other first-class Java collection. If your tech stack has Valkey instead of Redis, you can use the valkey-search module for high-grade vector searches, as it is also supported by Redisson and the RVectorSet API.
This guide covers everything Java developers and their teams need to know about managing vector sets in Valkey or Redis, with code samples, a thorough look at the RVectorSet engine, and how this approach compares to index-based vector search on both Redis and Valkey. Let's get started with a detailed look at Redis 8 vector sets.
What Is a Vector Set and Why Is It Important?
A vector set is essentially a large array of data with some unique capabilities. It's these special abilities that have made vector sets critical in the modern era of AI-enabled applications.
Historically, an enterprise tech stack was built around row-based databases (like PostgreSQL) for transactional processing and column-based databases (like Snowflake) for large, analytical aggregations. While these platforms still have value, they're designed for deterministic queries — finding exact keyword matches, filtering by strict numerical ranges, or joining tables based on distinct keys. In other words, they work best when the queries return exact matches. When users input synonyms or want an automatically generated list of related concepts, traditional databases tend to fall short without add-ons.
The era of AI applications has only made these limitations stand out. Vector sets solve these problems through the concept of similarity search. Instead of looking for exact matches, a vector engine calculates the mathematical distance between vectors in a multi-dimensional space. Data points that share similar meanings are clustered closer together. When a user submits a search request, the system converts the query into a vector and instantly retrieves its "nearest neighbors." Vectors and similarity searches power the advanced features required by today's enterprise apps, like semantic search and recommendation engines.
What Are Vector Sets in Redis 8?
The vector sets data type is one of the marquee features introduced in Redis 8. Before this release, executing vector searches required the Redis Query Engine (formerly the RediSearch module) to maintain complex secondary indexes. The new data type makes vector searches part of Redis's built-in functionality, and it's optimized for embedding storage and similarity calculations.
At first glance, a vector set functions much like a standard sorted set. However, instead of associating each element with a scalar floating-point score, the element is mapped to a high-dimensional vector. Operations are highly efficient, fully in-memory, and executed via these simple commands:
VADDinserts a new element and its associated vector into the set.VSIMexecutes a similarity search, returning the nearest neighbors to a query vector based on cosine similarity.VCARDandVDIMreturn the total number of elements and the dimensionality of the vectors, respectively.VEMBretrieves a specific vector by its element name.
Since Valkey forked from Redis at version 7.4, it doesn't support the vector sets data type or the above commands. However, Valkey does support vector similarity search via its official valkey-search module, which is supported in version 8.1.1 and higher. This module provides approximate nearest neighbor algorithms for high-dimensional similarity search and enables indexing and searching billions of vectors. Throughout the rest of this guide, you'll find instructions for leveraging valkey-search where appropriate.
How to Use the Redisson RVectorSet API in Java
Redisson's RVectorSet API provides an intuitive Java interface to Valkey/Redis vector sets functionality that developers will be immediately comfortable with. RVectorSet eliminates the need for your dev team to manually construct raw binary payloads or string-based commands. Initializing RVS only requires you to import a few interfaces and classes, then issue one line of code:
import org.redisson.api.RVectorSet;
import org.redisson.api.RedissonClient;
import org.redisson.api.search.VectorAddArgs;
import org.redisson.api.search.VectorSimilarArgs;
import java.util.List;
RVectorSet vectorSet = redisson.getVectorSet("document-embeddings");
Ingesting Data (VADD)
To store an embedding, use the add method alongside the VectorAddArgs builder. You can attach raw vector coordinates and inject optional JSON attributes, which you can later use for application-side filtering:
vectorSet.add(VectorAddArgs.element("doc-123")
.vector(0.12, -0.34, 0.56, 0.78)
.attributes("{\"category\": \"finance\", \"year\": 2024}"));
Retrieving Nearest Neighbors (VSIM)
The getSimilar method executes the search. One advantage of RVectorSet is its ability to search by an existing element's ID, which helps avoid the overhead of sending a large, raw vector over the network just to find related items:
// Search using a newly generated query vector
List hits = vectorSet.getSimilar(
VectorSimilarArgs.vector(0.15, -0.30, 0.55, 0.80).count(10));
// Highly efficient: Search by an existing element's ID
List related = vectorSet.getSimilar(
VectorSimilarArgs.element("doc-123").count(5));
Understanding HNSW and Quantization for Vector Search
When dealing with large amounts of data in vectors, engineering managers and technical leads are naturally concerned about system performance, memory allocation, and other resource utilization. Redis 8 addresses all these concerns through its underlying index structure and memory compression techniques.
HNSW (Hierarchical Navigable Small World): HNSW graphs organize vectors into a multi-layered hierarchy, enabling search algorithms to quickly find nearest neighbors, even as the dataset scales into the millions.
Quantization (memory compression): Storing millions of 32-bit floating-point vectors requires substantial RAM. Redis 8 natively supports quantization to aggressively reduce cloud infrastructure costs:
Q8 (8-bit quantization) reduces memory consumption by 4x compared to full precision, while maintaining roughly 96% recall accuracy. For the vast majority of enterprise applications, this is the optimal balance of cost and precision. Q8 is the default setting.
BIN (binary quantization) compresses vectors down to single bits, achieving up to a 32x memory reduction and massive speed gains, albeit at a noticeable cost to recall. Ideal for coarse, first-pass filtering.
NOQUANT retains full 32-bit float precision for mission-critical tasks where perfect recall is mandatory.
Building a Java Recommendation Engine with Redis
Now, let's see how you might use the tools in a real-world application and use case — an e-commerce platform that needs to generate real-time product recommendations. Assuming your machine learning pipeline has created the embeddings for your entire product catalog, you can utilize RVectorSet to build a highly responsive engine. Here's how:
RVectorSet catalog = redisson.getVectorSet("product-embeddings");
// 1. Ingest the product catalog
catalog.add(VectorAddArgs.element("sku-501")
.vector(runningShoeVector)
.attributes("{\"category\":\"footwear\", \"price\":89.99}"));
catalog.add(VectorAddArgs.element("sku-777")
.vector(hikingBootVector)
.attributes("{\"category\":\"footwear\", \"price\":129.99}"));
// 2. Serve "Similar Products" based on what the user is viewing
List recommendations = catalog.getSimilar(
VectorSimilarArgs.element("sku-501").count(8));
Running the Java Vector Set Demo Locally
You can test out this sample Java application with vector sets locally by spinning up a Redis 8 instance in Docker, like this:
docker run -p 6379:6379 redis:unstable
Next, add the Redisson dependency to your build. Here's how to do that in Maven:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.44.0</version>
</dependency>
Now, initialize the Redisson client, populate a demo space with 4-dimensional vectors, and query the engine for tailored results:
import org.redisson.Redisson;
import org.redisson.api.RVectorSet;
import org.redisson.api.RedissonClient;
import org.redisson.api.search.VectorAddArgs;
import org.redisson.api.search.VectorSimilarArgs;
import org.redisson.config.Config;
import java.util.ArrayList;
import java.util.List;
public class VectorSetDemo {
public static void main(String[] args) {
// Initialize Redisson
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
// Connect to the native Vector Set
RVectorSet catalog = redisson.getVectorSet("product-embeddings");
// Seed data
catalog.add(VectorAddArgs.element("sku-501")
.vector(0.90, 0.10, 0.80, 0.20)
.attributes("{\"category\":\"footwear\", \"price\":89.99}"));
catalog.add(VectorAddArgs.element("sku-777")
.vector(0.88, 0.14, 0.76, 0.25)
.attributes("{\"category\":\"footwear\", \"price\":129.99}"));
catalog.add(VectorAddArgs.element("sku-902")
.vector(0.10, 0.95, 0.05, 0.88)
.attributes("{\"category\":\"electronics\", \"price\":59.99}"));
// Query the graph, requesting one extra record to account for the query item itself
List similar = new ArrayList<>(catalog.getSimilar(
VectorSimilarArgs.element("sku-501").count(4)));
// Remove the source item from the final recommendation pool
similar.remove("sku-501");
System.out.println("Recommended SKUs: " + similar);
// Clean up resources
redisson.shutdown();
}
}
You can modify or expand this local demo to your tastes. For example, you might attach richer JSON attributes or layer a FILTER to graduate from a demo to a recommendation service.
The Power of Vector Searches in Your Java Code
Vector sets are the key to enterprise applications in the AI era. By leveraging Redis 8's new data type or valkey-search alongside the Redisson API, you can easily leverage the power of vector searches in your Java code. Both the community edition of Redisson and Redisson PRO allow developers to harness the speed and modern functionality of Valkey and Redis with familiar Java elements.