Skip to content

feat(index): tiered-index backend behind an opt-in fork pin — incremental adds replace periodic rebuilds#1794

Merged
jamie8johnson merged 2 commits into
mainfrom
feat-tiered-index
Jun 11, 2026
Merged

feat(index): tiered-index backend behind an opt-in fork pin — incremental adds replace periodic rebuilds#1794
jamie8johnson merged 2 commits into
mainfrom
feat-tiered-index

Conversation

@jamie8johnson

Copy link
Copy Markdown
Owner

feat(index): tiered-index backend behind a fork pin — incremental adds replace periodic rebuilds (opt-in)

The "kill the periodic HNSW rebuild" roadmap item, unblocked by consuming our own reviewed cuvs PR (NVIDIA/cuvs#2235) early via fork branch jamie8johnson/cuvs@cqs-tiered-26.6 (= the PR branch + a 26.6 version pin; the upstream PR branch is untouched; conda libcuvs 26.06 exports the full tiered C API).

  • Hard rail (verified empirically): the [patch.crates-io] fork pin ships commented out; default and cuda-index builds resolve official crates.io cuvs 26.6 (committed Cargo.lock has zero fork refs). The backend lives behind a new tiered-index feature that requires uncommenting the pin. All three configs pass clippy --all-targets.
  • Backend: TieredBackend registers above CAGRA in the priority table, runtime-gated by CQS_TIERED_INDEX=1; selection falls through to CAGRA→HNSW exactly as before when not opted in. Score conventions mirror cagra.rs per metric.
  • Watch integration: with tiered active, the threshold-driven periodic full rebuild gates off — incremental adds extend the brute-force tier with no rebuild (the defining contract, pinned by the GPU smoke: build 512 → search → extend → the new vector immediately findable). HNSW/CAGRA rebuild paths fully intact.
  • Persistence verdict: cuVS has no tiered serialize — the index rebuilds on daemon restart only (cold-start cost ≈ the CAGRA build it replaces; documented in module/CONTRIBUTING/README). Follow-up flagged: a daemon-held handle for true O(batch) per-cycle extend (currently each invalidation epoch rebuilds from store — still no periodic rebuild).
  • Docs honesty: found and fixed another stale README fork claim (cited the long-merged feat(mcp): Phase 0 — JsonSchema on command-core input structs #2019 patch and 26.4 versions); README/CONTRIBUTING now state the real pin policy and its retirement plan (the chore(deps): cuvs fork -> official 26.6.0 + libcuvs 26.06 #1679 playbook when feat(serve): add the impact / what-breaks enrichment to the callers view (closes #2129) #2235 merges upstream).

GPU smoke passed on the A6000 (single-threaded, daemon-only context). fmt + clippy clean across configs.

🤖 Generated with Claude Code

jamie8johnson and others added 2 commits June 11, 2026 17:53
…s replace periodic rebuilds (opt-in)

- New `tiered-index` cargo feature builds the cuVS tiered index backend
  (`src/tiered.rs`): a brute-force tier absorbs incremental `extend`s and stays
  searchable immediately, while the CAGRA ANN tier compacts inside cuVS — the
  watch loop's periodic full HNSW rebuild becomes a no-op when active.
- `TieredBackend` registers at priority 150 (above CAGRA's 100) via the
  `register_index_backends!` table; gated runtime-on by `CQS_TIERED_INDEX=1`,
  so default and CAGRA selection paths are unchanged even with the feature
  compiled in.
- Distance/score conventions mirror cagra.rs: Cosine keeps cuVS L2Expanded
  (`1 - d/2`), DotProduct sets InnerProduct (raw IP). ndarray_015 across the
  cuVS boundary; `unsafe impl Send/Sync` mirroring CagraIndex.
- Watch integration: `tiered_index_active()` gates off the threshold-driven
  full HNSW rebuild when tiered serves (cheap incremental HNSW insert + base
  router stay live); HNSW/CAGRA rebuild paths fully intact.
- Persistence: the cuVS C API has no tiered serialize/deserialize, so the
  tiered index is never persisted — the daemon rebuilds it from the store on
  restart. This still kills the *periodic* rebuild; only the cold-start build
  remains (same cost as the CAGRA build it replaces).
- Fork pin: `cuvs::tiered_index` ships via `[patch.crates-io]` →
  jamie8johnson/cuvs branch cqs-tiered-26.6 (commit 5081e4eb), which is the
  upstream PR branch (NVIDIA/cuvs#2235) + a version-pin 26.8.0→26.6.0. The
  patch block is COMMENTED OUT by default: plain `cuda-index` and crates.io
  builds resolve official cuvs 26.6 with no tiered symbols required (HARD
  RAIL, verified). Uncomment + `--features tiered-index` to build the backend.
- Docs: CONTRIBUTING "Tiered-index fork pin" section (what/why/retirement via
  the #1679 playbook), README GPU section corrected (deleted a stale fork
  claim that lied about a #2019 patch + wrong 26.4 version; now states the
  current truth), env knobs documented, CHANGELOG entry.
- Tests: backend ordering (3 backends, tiered leads), env override, build-param
  construction; an `#[ignore]` GPU smoke pinning build→search→extend→search
  (extended vector immediately findable as its own NN, no rebuild).

Residual (issue-worthy): the watch loop does not yet hold a persistent tiered
handle to call `extend` per-cycle — the served path rebuilds tiered from store
on cache invalidation (still no periodic rebuild). Wiring a daemon-held tiered
handle is the proper follow-up that turns each incremental add into an O(batch)
`extend` instead of a from-store rebuild.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant