cuVS: GPU Vector Search and Clustering From NVIDIA
cuVS - a library for vector search and clustering on the GPU
At a glance
- What is it?
- cuVS is NVIDIA's Apache-2.0 library for approximate nearest neighbors and clustering on the GPU, built on RAFT and exposed through Python, C++, C and Rust APIs. It is the right layer if you already own NVIDIA hardware and need to build indexes fast, and the wrong one if you cannot pin a CUDA toolchain.
- Who is it for?
- Adopt cuVS if you control the GPU and the CUDA version, and you want index construction and search to share one code path across Python, C++, C and Rust. Do not adopt it if your serving fleet is CPU-only or your CUDA runtime drifts faster than your release cadence, because the library ties you to NVIDIA toolchains and to a dated release train.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Cuda, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem cuVS targets: index build time on embeddings
Approximate nearest neighbor search has two cost centers. The first is index construction, which is a full pass over the dataset and, for graph-based methods, a graph construction problem on top of it. The second is query latency at whatever throughput you need. cuVS attacks both on the GPU, and the README is explicit that the library "contains state-of-the-art implementations of several algorithms for running approximate nearest neighbors and clustering on the GPU." The clustering half matters as much as the search half. The README lists K-means and HDBSCAN among the algorithms that depend on vector search as a step, plus UMAP and t-SNE for visualization, and k-NN graph construction for feeding graph analysis tools such as GraphBLAS and cuGraph.
The audience is narrower than the topic list suggests. If you are building a retrieval augmented generation pipeline, a recommender, or an image, text, audio or molecular search service, and you already have NVIDIA GPUs in the build or serving path, cuVS is aimed at you. The README also names model training as a use case, which is the giveaway: this is a library for people whose data already lives on a GPU, not a drop-in replacement for a CPU vector database. The stated primary goal is to "simplify the use of GPUs for vector similarity search and clustering," which is a claim about removing CUDA plumbing, not about beating any particular index on recall.
How cuVS is layered: RAFT primitives under an algorithm API
cuVS sits on top of RAFT, the RAPIDS library of machine learning primitives. The README describes RAFT as providing "all the necessary routines for vector search and clustering on the GPU," with cuVS supplying the algorithm-level layer above it. That split matters for anyone evaluating the maintenance burden: the low-level kernels, memory handling and device resource management live in RAFT, and cuVS composes them into named algorithms such as CAGRA.
The data flow visible in the README is consistent across languages. You hold a dataset as a device matrix (in C++ it is a raft::device_matrix_view<float>), you construct an index_params object, and you call build with a resources handle, the params, and the dataset. Search is the mirror image. The C API makes the boundary explicit: cuvsDatasetMakeStandardView converts a DLManagedTensor into a cuvsDataset_t view, which is then passed to cuvsCagraBuild. DLPack is the interchange format, and the Rust example imports DLTensorView and AsDlTensor from the cuvs crate, so the same tensor can cross a language boundary without a copy through host memory.
One design consequence worth flagging. The README advertises interoperability as "build on GPU, deploy on CPU." That is a real architectural commitment, not a footnote, and it is the reason the index format is not simply a GPU-resident blob. If your plan is to build nightly on a GPU box and serve from CPU nodes, that path is intended. If your plan is to serve from the GPU that built the index, you are using a subset of what the library offers.
Getting a CAGRA index built: the four API surfaces
The README's getting-started section is one task repeated in four languages: train an approximate nearest neighbors index for CAGRA. In Python the sequence is `from cuvs.neighbors import cagra`, then `index_params = cagra.IndexParams()`, then `index = cagra.build(index_params, dataset)`. Note that build takes the params first and the dataset second, which is the opposite order from the C++ signature.
In C++ you include `<cuvs/neighbors/cagra.hpp>`, declare a `raft::device_matrix_view<float>` for the dataset, construct a `raft::device_resources res`, and call `cagra::build(res, index_params, dataset)`. The resources handle is the piece that does not appear in the Python example, and it is where device selection and stream context live. In C the pattern is manual lifetime management: `cuvsResourcesCreate`, `cuvsCagraIndexParamsCreate`, `cuvsCagraIndexCreate`, then `cuvsCagraBuild`, then a matching set of destroy calls for the dataset view, the index, the params and the resources. The Rust example pulls `DistanceType`, `IndexParams` and `SearchParams` from `cuvs::neighbors::cagra` and the DLPack view types from the crate root.
That C example is the honest one about cost. Four create calls and four destroy calls for a single build means cuVS does not hide allocation from you at the C level. The README points to self-contained examples in the `examples` directory, including drop-in CMake project templates for both C++ and C, which is the fastest way to confirm the ABI you are linking against.
Install channels and the CUDA 13 binary-size note
cuVS ships pre-built packages through conda and pip, and as a tarball from NVIDIA's download page, with separate packages per supported language. The README does not enumerate the package names beyond one: `libcuvs-static`, the static conda package, which it recommends to anyone for whom binary size is a concern.
The reason is a note that deserves more attention than it usually gets. Builds for CUDA 13 are roughly half the size of CUDA 12 builds, which the README attributes to improved compression rates in the newer supported CUDA drivers. The README states that the CUDA 12 builds will adopt the newer drivers in Spring of 2026, bringing them down to roughly the CUDA 13 size. Until then, the size difference is real and version-dependent, and it is not something you can fix by choosing a different index algorithm.
Read that note as a constraint, not a curiosity. Your CUDA major version determines your artifact size today, and the fix is scheduled rather than available. If you are shipping a container image or a native binary and size is a hard limit, the static package or a source build is the documented escape hatch. There is no dynamic-link workaround described.
Where cuVS is the wrong tool
The clearest limitation is the one the README never has to state: cuVS requires NVIDIA GPUs and a CUDA toolchain, and the library's own pitch is that it "shoulders the burden of keeping non-trivial accelerated code up to date as new NVIDIA architectures and CUDA versions are released." That is a benefit only if you want someone else to own that burden. If your organization pins CUDA versions slowly, or runs a mixed fleet where some services have no GPU, you have taken on a dependency whose value proposition is tied to a release cadence you do not control.
The release history supports a second caution. The recent tags are v26.08.01, v26.08.00 and v26.06.00, with the two August releases a day apart. A version scheme tied to a calendar train with patch releases inside days of each other means the upgrade surface is continuous. There is no long-term support line visible in the supplied material, and the README does not describe a compatibility policy for index formats across versions. If you build an index with one release and try to load it with another, the material here gives you no guarantee either way. That is a question to resolve before you commit to persisting indexes.
A third case: work that is not a nearest neighbor problem at all. cuVS is a library, not a service. There is no server, no query endpoint, and no persistence layer in what the README describes. If you need a running vector store with replication and a REST API, cuVS is a component you would embed in one, and the README frames it that way by noting it "can be used directly or through the various databases and other libraries that have integrated it."
faiss as the comparison point, and where the approaches diverge
The obvious alternative for approximate nearest neighbors is faiss, which offers a broad set of index types with CPU and GPU implementations. The difference in approach is architectural rather than a matter of which index is faster. faiss presents a catalog of index families (flat, IVF, HNSW, PQ variants) that you select and tune, and the GPU path is one implementation choice among several. cuVS is built as a layer over RAFT primitives, and the README's framing is that cuVS supplies the routines and shoulders the CUDA maintenance, with RAFT underneath. The result is a narrower, more opinionated algorithm set with a consistent API shape across four languages, and a DLPack-based tensor boundary that faiss does not use in the same way.
A second alternative is a CPU-first vector database, which is the right answer when your serving fleet has no GPUs. The README's own interoperability claim, "build on GPU, deploy on CPU," is the bridge for that case, and it is the honest way to use cuVS without GPUs in production. Pick cuVS when index build time on large embedding sets is the bottleneck and the hardware is already there. Pick a CPU index when the build is fast enough on CPU, because then you are paying for a CUDA toolchain to solve a problem you do not have.
Licence and the maintenance you are signing up for
cuVS is Apache-2.0. That is a permissive licence with an explicit patent grant, and it is the same licence used across much of the RAPIDS stack, which simplifies compliance if you already ship RAFT or cuGraph. The supplied material does not include a NOTICE file or describe third-party bundled dependencies, so if your process requires a full dependency licence audit, that is a check to run against the repository rather than something this review can settle. Nothing here is legal advice.
The maintenance cost is the part worth pricing carefully. You are depending on RAFT, on a CUDA version, and on a release train that ships patch versions within days of each other. The README's own mitigation for the one concrete cost it names (binary size) is to link statically via `libcuvs-static` or build from source, which shifts work onto your build system. The README also notes that the CUDA 12 size fix is scheduled for Spring of 2026, so anyone on CUDA 12 between now and then is carrying a larger artifact with no dynamic-link fix available. Budget for a CUDA upgrade as part of adopting cuVS, not as a separate later project.
Editorial conclusion
Adopt cuVS if you control the GPU and the CUDA version, and you want index construction and search to share one code path across Python, C++, C and Rust. Do not adopt it if your serving fleet is CPU-only or your CUDA runtime drifts faster than your release cadence, because the library ties you to NVIDIA toolchains and to a dated release train. Verify three things before committing: which CUDA version your target hosts run, whether the pre-built package or a static libcuvs-static build fits your binary-size budget, and whether the language you write in is one of the four the README shows CAGRA examples for.
Community notes