Skip to Content
We are live but in Staging 🎉
Knowledge BaseVector DatabaseIndexingBinary Vector IndexesBIN_IVF_FLAT (Binary IVF_FLAT)

BIN_IVF_FLAT is an inverted-file (IVF) index for binary vectors. It accelerates similarity search by partitioning your binary vector space into nlist buckets (clusters). At query time, Dodil searches only the most relevant buckets and then does a flat (exact) comparison inside those buckets.

This is a good default when you need faster binary search than a full scan, while keeping behavior simple and predictable.

When to use it

Use BIN_IVF_FLAT when:

  • Your embedding field is binary (e.g., perceptual hashes, binary signatures).
  • You want a strong balance between speed and recall.
  • You prefer a straightforward index that is easy to tune.

Typical binary use cases:

  • Near-duplicate detection (images, documents, frames)
  • Similarity lookup for perceptual hashes
  • Binary embeddings / compact signatures

How it works

  1. Index build: vectors are grouped into nlist clusters (buckets).
  2. Search: Dodil selects the top nprobe buckets relevant to your query.
  3. Exact scan: a flat comparison runs only within those selected buckets.

Two knobs matter most:

  • nlist: how many buckets exist
  • nprobe: how many buckets to search per query

Supported metrics (binary)

Common metrics for binary vectors:

  • HAMMING
  • JACCARD

Pick the one that matches how your binary vectors are produced.

Create the index

Below is a typical flow using the Dodil SDK.

from dodil import Client from dodil.vbase import VBaseConfig # Authorize c = Client( service_account_id="...", service_account_secret="...", ) # Connect to VBase vbase = c.vbase.connect( VBaseConfig( host="vbase-db-<id>.infra.dodil.cloud", port=443, scheme="https", db_name="db_<id>", ) ) # Create a BIN_IVF_FLAT index on a binary vector field vbase.create_index( collection_name="my_collection", field_name="binary_vector", index_name="binary_vector_index", index_type="BIN_IVF_FLAT", metric_type="HAMMING", params={ "nlist": 128, }, )

Index parameters

  • nlist (integer)
    • What it is: number of buckets (clusters)
    • Effect:
      • higher nlist → smaller buckets → better pruning potential, but more build/metadata cost
      • lower nlist → larger buckets → faster build, less pruning

Practical starting points:

  • Small datasets: nlist = 64 or 128
  • Medium datasets: nlist = 256 to 1024

Tip: if you’re unsure, start with nlist = 128 and tune from there.

Search with BIN_IVF_FLAT

Once the index is built, tune query performance with nprobe.

results = vbase.search( collection_name="my_collection", anns_field="binary_vector", data=[query_binary_vector], limit=10, search_params={ "params": { "nprobe": 8 } }, ) print(results)

Search parameters

  • nprobe (integer)
    • What it is: how many buckets to search
    • Valid range: 1 .. nlist
    • Effect:
      • higher nprobe → better recall, higher latency
      • lower nprobe → faster, but may miss neighbors

Practical starting point:

  • If nlist = 128, try nprobe = 8.
  • If recall isn’t good enough, increase gradually: 8 → 16 → 32.

Tuning recommendations

  • Keep nprobe low (e.g., 4–8)
  • Use a moderate nlist (e.g., 128–512)

If you want higher recall

  • Increase nprobe (e.g., 16–64)
  • If buckets are too large, increase nlist (watch index build time)

Common gotchas

  • Partitions vs. parallelism: Partitions (Kafka) and vector index partitions are unrelated—nlist controls vector search bucketing.
  • Index build time: Bigger nlist increases build and resource usage.
  • Field type must be binary: Ensure your field is a binary vector field (not dense float vectors).

Next: If you haven’t already, learn how to load and release collections for predictable performance in production.

Last updated on