Rebuild and Optimize

Over time, as you insert, upsert, and delete vectors, the index structure can become fragmented and suboptimal. brinicle provides two operations to restore index performance: graph optimization and compact rebuild.

When to Rebuild or Optimize

After many delete or insert/upsert operations, you may notice:
  • Increased query latency — searches take longer as the graph structure degrades
  • Reduced recall — search quality drops because deleted nodes fragment the graph
  • Growing delta segment — inserted vectors accumulate in the delta segment, increasing its size relative to the main segment
brinicle provides a convenient method to check if a rebuild would be beneficial:
if engine.needs_rebuild():
    print("A rebuild is recommended")

Graph Optimization

Use optimize_graph(...) to run conditional maintenance.
engine.optimize_graph()
optimize_graph() checks whether the index needs rebuilding. If the update or delete ratio crosses the delta_ratio threshold, Brinicle rebuilds the graph. Otherwise, it does nothing. For unconditional compaction, use rebuild_compact().

When to Use Optimization

Graph optimization is a good choice when:
  • You’ve done a moderate number of deletions and want to recover performance
  • You don’t want the downtime associated with a full rebuild
  • The delta segment is still small relative to the main segment

Compact Rebuild

rebuild_compact() performs a full rebuild of the index, creating a new compact graph from scratch that contains only the live (non-deleted) vectors:
engine.rebuild_compact()
This:
  • removes deleted records physically
  • merges alive records from the main and delta indexes
  • builds a new main index
  • clears the delta index
You can also pass build parameters:
engine.rebuild_compact(
    M=48,
    ef_construction=1024,
    ef_search=512,
    build_n_threads=4,
)

Rebuild Parameters

ParameterTypeDefaultDescription
Mint16HNSW connectivity for the rebuilt graph
ef_constructionint200Build-time search width for the rebuild
ef_searchint64Query-time search width for the rebuilt graph
build_n_threadsint1Number of build threads
seedint0RNG seed for reproducibility

When to Use Rebuild

A compact rebuild is the best choice when:
  • You’ve done significant deletions and the graph is heavily fragmented
  • The delta segment has grown large and is affecting search performance
  • You want to change HNSW parameters (e.g., increase M for better recall)
  • You need maximum search performance for latency-sensitive applications

Rebuild Performance

The rebuild process reads all live vectors and constructs a new graph, so its duration is proportional to the number of live vectors. For an index with 1M vectors and typical parameters, a rebuild may take several minutes. Plan rebuilds during low-traffic periods in production environments.

Optimization vs. Rebuild

Aspectoptimize_graph()rebuild_compact()
BehaviorConditional — rebuilds only if threshold crossedUnconditional — always rebuilds
SpeedFast (when no rebuild needed)Slow
Quality improvementModerateMaximum
Merges delta segmentYes (when triggered)Yes
Can change HNSW paramsNoYes
DowntimeMinimal or noneSignificant
Recommended forConditional maintenanceHeavy modifications
For production systems, a common strategy is to call optimize_graph() periodically (e.g., daily) — it will only rebuild when needed — and use rebuild_compact() explicitly after major data changes.