Check IVF coverage and balance
The language tabs use earlier client interfaces. Check SDK versions and connection setup before running them.
Inspect whether stored vectors are covered by the index and whether one partition contains too many entries. This request reports status; it does not rebalance.
Before you run it: Stale postings can inflate counts. A recommendation of none does not replace a coverage check.
Complete centroid training first. This is an IVF status check, not a way to create that index. Coverage asks whether stored vectors have index entries; balance asks whether those entries are spread evenly across groups. Check coverage before interpreting the balance recommendation.
- Read IVF statusUse a table with installed centroids.
- Compare stored and indexed countsCheck coverage and unindexed vectors first.
- Inspect group sizesCompare the largest partition with the average.
- Plan any retrainingUse the report to decide on a separate corrective action.
Follow the example
- Request status for an IVF table.
- Check coverage.
- Compare the largest partition with its mean size.
- Use the recommendation to decide whether to retrain.
Run the request
curl "https://$OC_HOST/v1/tenants/$OC_TENANT/vector/shop.products/ivf-rebalance-status" \
-H "Authorization: Bearer $OC_TOKEN"Check the result
The response includes counts, skew and a recommended action.
{
"total_live": 100000,
"partitions": 1024,
"live_per_cell": [112, 96, 143, 87 /* ... one entry per cell ... */],
"skew": 1.46,
"action": "none",
"stored_vectors": 100000,
"unindexed": 0,
"coverage": 1.0
}action is one of "none", "recommended" or "required", set from skew against the engine's thresholds.
Response fields
| Field | Required | Notes |
|---|---|---|
| total_live | - | Vectors with a cell posting, summed across every cell. |
| partitions | - | Installed centroid count. Equals the length of live_per_cell. |
| live_per_cell | - | Posting count per cell, indexed by cell id. A cell that was never written reports 0. |
| skew | - | max(live_per_cell) / mean(live_per_cell), or 0.0 on an empty corpus. A perfectly even index sits at 1.0. |
| action | - | "recommended" above a skew of 2.0, "required" above 5.0, otherwise "none". |
| stored_vectors | - | Vectors stored under this table, counted from the keys, whether or not they are cell-assigned. |
| unindexed | - | stored_vectors - total_live. Vectors with no cell posting: written before the centroids were installed, or left behind by a skipped backfill. |
| coverage | - | total_live / stored_vectors, clamped to 1.0. This is the number to alert on. |
Understand the behavior
The report walks each cell's posting list and counts entries; it does not decode the payloads behind them. That makes it cheap enough to poll, and it means "live" is a posting count rather than a verified row count - an index with stale postings from an interrupted re-install can over-report total_live. Re-training and re-installing is the cleanup, not a per-call scan.
stored_vectors, unindexed and coverage exist for one failure shape that every other field hides: a table with ten thousand vectors stored and zero of them indexed. Nothing else on this response raises a flag there - every cell is empty, so skew is 0.0 and action is "none" - while every IVF query against that table returns nothing.
Skew matters for latency rather than correctness. A query probes a fixed number of cells; if one cell holds ten times its share, the queries that land on it do ten times the work. That is what the action hint is tracking.
Important limits and checks
- Reading
total_livealone. It cannot distinguish "the index is small" from "the index is empty and the data is elsewhere". Readcoveragewith it, every time. - Calling it on an HNSW table. There are no centroids, so the route answers 503 with
"error": "ivf_centroids_not_installed". That is the same refusal an IVF query gets, and it means the same thing. - Waiting for a rebalance to happen. Nothing is automatic.
"action": "required"is the engine telling you to call train-and-install-centroids yourself. - Treating a low
coverageas a query-tuning problem. Nonprobesetting reaches a vector that has no posting. Re-install the centroids so the backfill runs.