Welcome to the new DOCS.vastdata.com. We've added new menus and a version selector, plus new persona and resource pages to help customers get started. Looking for a previous article? Use the docs search.

Performance and sizing

Prev Next

Applies to VAST Cluster 5.5.

This page covers cluster-level performance and sizing for VAST Vector Search: the state of the index, what a search reads, how load spreads, what a vector table costs in space, and what your platform team can see. How to write the query itself is in query design. There are no published capacity or throughput figures for VAST Vector Search on 5.5, so measure with your own data.

What you control and what the cluster controls

Area Who controls it Where to read more
Metric, element type, dimension and quantization You, when you create the table (none can be changed later) Create an index, quantization
The query shape, the columns and LIMIT You Ask for less
Probe settings for a session You Search session settings
Client connections and how they spread You Spread the load
Background clustering of the index The cluster Check the index first
The Query Engine pool and the database pool Platform team Cluster settings to ask about

Vector search runs in the VAST Query Engine, which is built into the CNodes. So searches use CNode CPU and memory, shared with the cluster's other work, including the background work that builds and refines the index.

Check the index first

A latency or recall number means little while the index is still being built. Newly inserted vectors can be searched straight away, while the index is updated in the background. Until then, a search reads those recent rows directly, outside the index, so right after a large load each search does more work than it will once the index has caught up. The background clustering also competes with your queries for CNode CPU.

Each vector index reports how far its background clustering has got:

Field Meaning
clustering_progress Clustering progress as a percentage, 0 to 100
clustering_progress_label The same progress as a grade: A+, A, B or C. A higher grade means more progress.

A new, empty table starts at 0 and C. Read them with GET /tables/show/ in the VMS REST API (CI/CD and automation), or ask your platform team, who see the grade in the table's view in the VAST Web UI.

A grade of C doesn't mean the index isn't used. A table of 1.2 million rows can stay at 0 and C for over an hour after loading, while its searches already read the index (what your platform team can see shows how to tell). While the background work runs, the row count that GET /tables/show/ and the SDK's table statistics report can be higher than the number of rows in the table; it comes back to the right number when the work finishes. Count rows with SELECT count(*) instead.

Run load tests when the grade is A or A+ and the cluster isn't busy loading. Otherwise, accept that you're measuring the extra cost of recent rows.

Ask for less

  • Use the index's query shape. A search that doesn't match it still runs, but it scans the whole table instead of walking the index, and one such query on a big table uses a lot of CNode CPU that other users of the cluster feel. The shape is in query design.
  • Return only the columns you need. Selecting the embedding column, or many wide columns, moves more data over the network for every result row.
  • Keep LIMIT to what you use. A larger LIMIT returns more rows, and more data, for every search.
  • Raise probes only when you've measured. The probe settings control how many clusters a search reads at each level of the index. The defaults are the supported starting point. Raising them generally improves recall and costs latency, CPU and memory, because each search reads more clusters. When you compare runs, pin the minimum and maximum to the same values so that every query reads the same amount. The settings are in search session settings, and how to measure the effect is in developer observability.

Trino and Spark don't use the vector index (limits). Search through the Query Engine.

Spread the load

One ADBC connection doesn't show what the cluster can do. Each search in flight uses memory on a CNode, so open several connections and spread them over the Query Engine pool's addresses, as you would for any VAST DataBase workload (spread work across endpoints). A connection stays on the address you give it, and so does every connection to the same address: nothing spreads them for you. Ask your platform team to watch CNode CPU while you load-test: if one CNode is busy and the rest are idle, your connections aren't spreading.

Quantization

scalar_8bit quantization (the default) uses less space, CPU and memory than none, at some cost in recall. You can't change it after the table is created, so measure first: build a sample table each way, compare recall at your LIMIT (Recall@K) against a none/none table or an exact search, and then create the real table. The settings and their allowed combinations are in quantization.

Your data

Real embeddings form clusters, and the index relies on that. Random data, such as Gaussian noise, doesn't cluster, so a test with random vectors shows worse recall and latency than you'll get with real embeddings. A mismatch between the metric and your embeddings (cosine against L2, or unnormalized vectors with inner product) also looks like a slow or wrong index. Check the embedding model's documentation for the metric it was trained for.

Space

A vector column takes roughly rows × dimensions × bytes per element: 4 bytes for VECTOR(FLOAT, d) and 2 for VECTOR(FLOAT16, d). On top of that, the index keeps its own structures, and how big they are depends on the quantization you choose when you create the table:

  • scalar_8bit (the default) stores compact 8-bit codes for clustering and search.
  • none keeps full-precision values, so it needs more space and memory.

There's also a maximum dimension, which depends on the cluster quantization, and none has the lower one (limits). A table with too many dimensions fails at CREATE TABLE with vector dimension <d> exceeds max supported dimension <max> for clustering quantization type <type> due to memory limitations (errors).

Loading and searching use different pools

Bulk loads through the Python SDK or S3 go to the ordinary database endpoints, which can be spread over many CNodes. Searches go to the Query Engine pool. Size and test them separately, not as one pool. See setup.

What your platform team can see

Signal Where What it tells you
Clustering grade (C to A+) The table's view in the VAST Web UI, or GET /tables/show/ Whether the index has caught up with your inserts (check the index first)
CNode CPU VAST Web UI analytics Whether searches and background clustering compete for CPU, and whether load spreads over the CNodes
top_n_num_processed_rows, top_n_num_returned_rows, top_n_query_latency_us The predefined VMS monitors Cluster Vast DB TopN and CNode Vast DB TopN, read with GET /api/v8/monitors/<id>/query/ How many rows the searches' top-k step compared. About the table's row count per search means the search scanned the table; a small fraction of it means it used the index.
vec_index_scan_num_l1_reads An ad hoc VMS query: GET /api/v8/monitors/ad_hoc_query/?object_type=cluster&prop_list=TabularQueryEngineMetrics,vec_index_scan_num_l1_reads Reads of the index's lowest level. Above zero, searches walked the index; zero for a search means it didn't use the index.

The counters are cumulative for the whole cluster and are sampled at intervals. To see what your searches did, read them before and after a run on a quiet cluster, and divide the difference by the number of queries. On a table of 1.2 million rows, for example, an index search compares a small fraction of the rows and reads the index's lowest level; the same search written as a similarity ordered descending compares all 1.2 million rows per query and reads no index level. A developer can also check a single query with EXPLAIN (query design).

The general VAST DataBase metrics (query latency, running queries, rows scanned) are described in what your platform team can see for VAST DataBase. There are no vector-specific alerts or call-home events described for 5.5. Don't expect the cluster to alert you when the index falls behind; check the clustering grade.

Admin task: send to your platform team. Ask them to share the clustering grade of your tables, CNode CPU and the TopN counters during your load tests. See Monitoring VAST DataBases.

Cluster settings to ask about

A Query Engine pool. The VAST Query Engine needs its own virtual IP pool with the Query Engine role (VAST Query Engine). Ask how many CNodes and addresses it has: that's what your search connections spread over. A Query Engine pool can't be modified after it's created (5.5.0 release notes), so agree its size before a load test, not during one. See setup.

A database pool for loading. Bulk loads use the ordinary VAST DataBase pool; see cluster settings to ask about for VAST DataBase.

See also