Skip to content
AI-200 Learn

Choose vector types and indexing strategies

Pick FLOAT32 vs FLOAT64, DIM, COSINE/L2/IP and FLAT vs HNSW for Azure Managed Redis vector indexes, and tune M, EF_CONSTRUCTION and EF_RUNTIME.

What this covers

A Redis vector index needs three choices: the data type of each vector, the distance metric and the indexing algorithm. Together they decide memory cost, accuracy and latency. This page explains each option with concrete numbers, gives a configuration table for common AI workloads, and shows how to measure the speed/accuracy trade-off of HNSW on your own data. The exam usually gives a scenario (dataset size, latency target, embedding type) and asks for the right combination.

Exam weight: Develop AI solutions by using Azure data management services (30–35%)

Skills measured

  • "Implement vector indexing to enable similarity search"

Key concepts

Vector data type

TYPEBytes per dimension1,536-dim vectorUse
FLOAT3246,144 B (about 6 KB)Default for AI embeddings. About 7 significant digits is more than the models need
FLOAT64812,288 B (about 12 KB)Specialized research only. It doubles memory and slows distance math

For one million 1,536-dim vectors, FLOAT32 needs about 6 GB for the raw vectors alone, before index overhead. FLOAT64 needs about 12 GB. Recent RediSearch versions also accept FLOAT16 and BFLOAT16 to save memory. The Learn module covers only FLOAT32 and FLOAT64.

Dimensions

DIM must equal the embedding model's output exactly. Common sizes are 384, 768, 1,024, 1,536 and 3,072. A mismatch makes ingestion skip the document or makes queries fail. If you switch embedding models, build a new index (and usually new keys).

Distance metrics

MetricMeasuresUse for
COSINEAngle between vectors, ignoring magnitudeText embeddings (OpenAI, Cohere, Sentence Transformers)
L2Straight-line (Euclidean) distance, including magnitudeImage embeddings, spatial data
IPInner (dot) productOnly vectors that are already normalized, or models trained for it

Match the metric your embedding model was trained with. The wrong metric still returns results, but the ranking means nothing.

FLAT vs HNSW

FLATHNSW
SearchExact, brute force against every vectorApproximate, graph navigation
Accuracy100%About 95–99% recall
Query timeGrows linearly (about 10 ms at 10k vectors, around 1 s at 1M)Milliseconds even at millions of vectors
Memory / buildLowest, fast insertsExtra graph memory, slower inserts
Choose whenFewer than about 10,000 vectors, prototypes, exact results neededMore than about 10,000 vectors, production, under 10 ms latency

HNSW (Hierarchical Navigable Small World) is a multi-layer graph. Upper layers make long jumps and lower layers refine locally, so a query touches only a small fraction of the vectors.

HNSW tuning parameters

ParameterWhen setDefaultEffect
MIndex creation16Edges per node. Higher gives better recall and uses more memory
EF_CONSTRUCTIONIndex creation200Candidates considered while building. Higher gives a better graph and a slower build
EF_RUNTIMECreation default, or per query10Candidates explored per query. Higher gives better recall and higher latency
EPSILONRange queries0.01Boundary slack for VECTOR_RANGE

The module's guidance is to start EF_RUNTIME around 50 and raise it to 100–200 if recall is too low. Use INITIAL_CAP (and BLOCK_SIZE for FLAT) to pre-size the index when you know the vector count.

Quick configuration guide

Use caseTYPEMetricAlgorithm
Text search, small corpusFLOAT32COSINEFLAT
Text search, large corpusFLOAT32COSINEHNSW
Image similarityFLOAT32L2HNSW
RecommendationsFLOAT32COSINEHNSW

How it works

Diagram source: flowchart LR Start{How many vectors?} -->|Under 10k or exact needed| Flat[FLAT] Start -->|Over 10k, latency under 10 ms| Hnsw[HNSW] Emb{Embedding type?} -->|Text| Cos[COSINE] Emb -->|Image or spatial| L2[L2] Emb -->|Pre-normalized| IP[IP] Hnsw --> Tune[Tune EF_RUNTIME 50 to 200]

Hands-on

Azure portal

  1. Size the instance for the vectors. For example, 1M x 1,536-dim FLOAT32 is about 6 GB raw plus HNSW graph and metadata, and roughly 20% of instance memory is reserved. A Balanced B20 or larger is a sensible starting point.
  2. After loading, check Used Memory Percentage in Metrics and scale up before it stays above 75%.

Azure CLI

Azure CLI / Bash
az group create --name rg-ai200 --location eastus
az redisenterprise create --name <cache-name> --resource-group rg-ai200 \
  --location eastus --sku Balanced_B20 \
  --clustering-policy EnterpriseCluster --eviction-policy NoEviction \
  --modules name=RediSearch

Python

Python
import time
import numpy as np
import redis
from redis.commands.search.field import TagField, VectorField
from redis.commands.search.index_definition import IndexDefinition, IndexType
from redis.commands.search.query import Query
from redis_entraid.cred_provider import create_from_default_azure_credential

provider = create_from_default_azure_credential(("https://redis.azure.com/.default",))
r = redis.Redis(host="<cache-name>.<region>.redis.azure.net", port=10000, ssl=True,
                credential_provider=provider)

# Text index: HNSW + COSINE with explicit build parameters
text_vec = VectorField("embedding", "HNSW", {
    "TYPE": "FLOAT32", "DIM": 1536, "DISTANCE_METRIC": "COSINE",
    "M": 16, "EF_CONSTRUCTION": 200, "EF_RUNTIME": 50})

# Image index: L2
image_vec = VectorField("image_embedding", "HNSW", {
    "TYPE": "FLOAT32", "DIM": 768, "DISTANCE_METRIC": "L2"})

# Small exact index: FLAT
flat_vec = VectorField("embedding", "FLAT", {
    "TYPE": "FLOAT32", "DIM": 1536, "DISTANCE_METRIC": "COSINE"})

r.ft("idx:docs").create_index(
    [TagField("id"), text_vec],
    definition=IndexDefinition(prefix=["docs:"], index_type=IndexType.HASH))

# Measure latency at different EF_RUNTIME values
query_vector = np.random.rand(1536).astype(np.float32)
for ef in (50, 100, 200):
    q = (Query(f"*=>[KNN 10 @embedding $query_vec EF_RUNTIME {ef} AS score]")
         .return_fields("id", "score").dialect(2))
    t0 = time.perf_counter()
    r.ft("idx:docs").search(q, query_params={"query_vec": query_vector.tobytes()})
    print(f"EF_RUNTIME={ef}: {(time.perf_counter() - t0) * 1000:.2f} ms")

Exam traps

ScenarioChoose
5,000 FAQ entries, exact answers requiredFLAT + COSINE
10M product embeddings, p99 under 10 msHNSW + COSINE
Recall too low on HNSW, latency OKRaise EF_RUNTIME (per query)
Memory too high, precision is fineFLOAT32 instead of FLOAT64
Vision-model embeddingsL2
Already-normalized vectors, fastest mathIP

Quick review

  • FLOAT32 uses 4 bytes per dimension (about 6 KB at 1,536 dims) and is the standard choice. FLOAT64 doubles that.
  • DIM must match the model output exactly.
  • Use COSINE for text, L2 for images or spatial data, and IP for normalized vectors.
  • FLAT is exact with linear time. HNSW is approximate (95–99%) and fast at scale.
  • HNSW parameters: M (16), EF_CONSTRUCTION (200) and EF_RUNTIME (10 by default, tunable per query).
  • Benchmark EF_RUNTIME against real data before production.

Practice

Practice: Azure Managed Redis vector indexing

Official references