Refresh a Vector Index

Build a Vector Index for the current source Table version with a durable Task.

In development

Rebuild frame-search after new frames land in frames. A search fails while the index covers an older Table version, so a refresh is the step that makes search available again. The build runs as a Task on a Worker and publishes the new index version in one commit.

In Studio, the Refresh action on the Vector Index does the same thing. This guide uses the Task directly, which also works from scripts and Automations.

Before you start

  • A Vector Index. See Create a Vector Index.
  • The branch ID and its head commit ID, and the Resource ID and version ID of the Vector Index at that commit. See Select an exact state. The Resource kind is vector-index, and the Resource ID is the Vector Index ID.
  • A Worker Pool that can run Tasks for the Project.

Refreshes produce codec version 3 by default. The packed_postings engine option accepts "true" to enable codec version 4. Codec version 4 requires compatible embedded clients and Connect hosts.

Read the current version

Read the version that the commit selects. Its definition names the source Table, and its build state shows the covered source version:

read = client.vector_indexes.read_version(vector_index_id, version_id)
print(f"dimensions: {read.definition.dimensions}")
if read.version.source_version_id is None:
    print("not refreshed")
else:
    print(f"covers source version: {read.version.source_version_id}")
physical = read.version.physical
print("not built" if physical is None else f"sealed with {physical.indexed_rows} rows")
FieldMeaning
definition.sourceResourceIdThe Catalog Resource ID of the source Table.
definition.metric, definition.dimensionsThe distance metric and the vector length.
version.sourceVersionIdThe source Table version that the build covers. Absent before the first build.
version.physicalThe sealed build, with indexedRows and partitions. Absent before the first build.

Submit the refresh Task

In an SDK, resolve the Vector Index on a branch and refresh it; the build reads the source Table's latest version on that branch. Over HTTP, submit a vectorIndexRefresh definition whose read target names the branch and, optionally, the exact commit to build from:

index = client.project("demo").branch("main").vector_index("frames_by_embedding")
task = index.refresh(mode="full")
if task is None:
    print("a refresh of this Vector Index is already waiting")
else:
    print(f"built {task.wait().versions[0].version_id}")

vectorIndexId and vectorIndexResourceId take the same value: the Vector Index's Resource ID. The Task checks your permission under both names. It needs write permission on the Vector Index and read permission on the source Table. It uses cpu-2 unless you select another resource profile in options. It allows three attempts.

Set mode to full. The vortex.ivf-rabitq engine rebuilds the whole index on every refresh.

The idempotency key makes a retry safe. Use a new key for each new refresh.

Verify the result

  1. Wait for the Task to reach a terminal status. See Tasks.
  2. Read published.versions and published.commitId. Use the result from wait() in SDK calls.
  3. Read the exact Vector Index version that the result identifies.
  4. Verify that version.sourceVersionId identifies the refresh source and that version.physical exists.
  5. Read version.physical.indexedRows for the indexed row count.

Troubleshooting

ProblemCause
The Task stays pendingNo Worker can run Tasks for the Project. Check the Worker Pool.
The Task fails because the Worker memory budget is too smallThe selected resource profile cannot fit the build for these vector dimensions.
The build exceeds its posting descriptor limitThe posting buffers cannot fit the index layout. A larger Worker or fewer partitions can reduce the descriptor count.
A search still fails as staleThe source Table changed after the commit that the Task read. Refresh again from the new head.
Found a problem? Edit this page or report an issue.

On this page