What is your question?
I benchmarked CAGRA native cosine search with a small self-search program and measured a QPS that seems lower than I expected from the cuVS ANN benchmarks. Is ~43.5k QPS a reasonable number for these parameters on an L4, or is something off? And which parameters would have the biggest impact on QPS?
Update (2026-08-26): The original reproducer used raw, unnormalized Cohere vectors with L2Expanded. I corrected the benchmark to use native cuVS CosineExpanded for both index construction and search, and updated the measurements below. The script still passes the input vectors to cuVS unchanged and does not pre-normalize them.
Reproduction
Minimal reproducer (self-contained script that builds cuVS from source and runs a tiny C++ benchmark using cuvs::neighbors::cagra::build / cuvs::neighbors::cagra::search):
https://github.com/marcelo-cjl/cuvs/blob/33ac4cfef430934cf4f4c583f942d0b429736133/cpp/bench/cuvs_cagra_self_search/cuvs_cagra_self_search.sh
Environment:
- Machine: AWS g6.4xlarge
- GPU: NVIDIA L4 23 GB
- Driver: 560.35.05
- cuVS: built from source at commit
33ac4cfe (Release, -DBUILD_TESTS=OFF -DBUILD_C_LIBRARY=OFF -DBUILD_CAGRA_HNSWLIB=OFF -DBUILD_MG_ALGOS=OFF -DCUVS_COMPILE_DYNAMIC_ONLY=ON, CMAKE_CUDA_ARCHITECTURES=native)
Dataset: VectorDBBench Cohere Medium, converted to .fbin (1,000,000 rows x 768 dims, float). This is a self-search workload: the same training file is used to build the index and as the query input. self_recall_at_1 is the fraction of queries where the top-1 label equals the query's own row id.
Index / search parameters:
| Parameter |
Value |
| dtype |
float |
| metric |
CosineExpanded |
| graph_degree |
64 |
| intermediate_graph_degree |
128 |
| topk |
1 |
| itopk_size |
32 |
| search_width |
1 |
| max_iterations |
0 |
| search_algo |
SINGLE_CTA |
Observed results from two searches against the same rebuilt cosine index:
| run |
stage |
rows |
dim |
search_ms |
qps |
self_recall_at_1 |
| 1 |
search |
1,000,000 |
768 |
22,993.9 |
43,489.8 |
0.995099 |
| 2 |
search |
1,000,000 |
768 |
22,996.2 |
43,485.5 |
0.995099 |
search_ms is measured with CUDA events around a single cuvs::neighbors::cagra::search call (1M queries in one batch); qps = rows * 1000 / search_ms.
Expected behavior
I was expecting higher throughput based on the cuVS ANN benchmarks. Specifically:
- Is ~43.5k QPS reasonable for native
CosineExpanded, SINGLE_CTA, search_width=1, topk=1, 1M x 768 float on an L4, or does it indicate a configuration problem?
- Which knobs have the biggest impact on QPS (e.g., multi-CTA search algorithm, larger
search_width/itopk_size, half precision, query batch size)?
- Is there an official way to run this exact native-cosine workload through
cuvs-bench so I can compare against a reference number?
What is your question?
I benchmarked CAGRA native cosine search with a small self-search program and measured a QPS that seems lower than I expected from the cuVS ANN benchmarks. Is ~43.5k QPS a reasonable number for these parameters on an L4, or is something off? And which parameters would have the biggest impact on QPS?
Reproduction
Minimal reproducer (self-contained script that builds cuVS from source and runs a tiny C++ benchmark using
cuvs::neighbors::cagra::build/cuvs::neighbors::cagra::search):https://github.com/marcelo-cjl/cuvs/blob/33ac4cfef430934cf4f4c583f942d0b429736133/cpp/bench/cuvs_cagra_self_search/cuvs_cagra_self_search.sh
Environment:
33ac4cfe(Release,-DBUILD_TESTS=OFF -DBUILD_C_LIBRARY=OFF -DBUILD_CAGRA_HNSWLIB=OFF -DBUILD_MG_ALGOS=OFF -DCUVS_COMPILE_DYNAMIC_ONLY=ON,CMAKE_CUDA_ARCHITECTURES=native)Dataset: VectorDBBench Cohere Medium, converted to
.fbin(1,000,000 rows x 768 dims, float). This is a self-search workload: the same training file is used to build the index and as the query input.self_recall_at_1is the fraction of queries where the top-1 label equals the query's own row id.Index / search parameters:
Observed results from two searches against the same rebuilt cosine index:
search_msis measured with CUDA events around a singlecuvs::neighbors::cagra::searchcall (1M queries in one batch);qps = rows * 1000 / search_ms.Expected behavior
I was expecting higher throughput based on the cuVS ANN benchmarks. Specifically:
CosineExpanded,SINGLE_CTA,search_width=1,topk=1, 1M x 768 float on an L4, or does it indicate a configuration problem?search_width/itopk_size, half precision, query batch size)?cuvs-benchso I can compare against a reference number?