O time de ML acabou de te pedir um “vector database” em produção. Você sabe operar PostgreSQL, Redis, Cosmos DB. Mas isso? É um banco de dados ou um índice de busca? Precisa de backup? Tem replicação? Qual o modelo de consistência?

Vamos abrir o capô.

O mapa pro profissional de infra

Conceito Vector DBO que fazEquivalente em infra
Vector/EmbeddingArray de floats que representa significadoUma row com 1536 colunas numéricas
Similarity searchBuscar vetores parecidosQuery com ORDER BY distance LIMIT K
Index (HNSW, IVF)Estrutura pra busca rápidaB-tree, hash index num banco relacional
DimensionTamanho do vetor (768, 1536, 3072)Largura da row (quantas colunas)
Distance metricComo calcular “parecido”Cosine similarity, Euclidean, dot product
Recall% de resultados corretos encontradosTaxa de acerto da recuperação (o que deveria aparecer apareceu?)

O problema fundamental

Num banco relacional, buscar é comparar valores exatos ou ranges. WHERE status = 'active' ou WHERE created_at > '2024-01-01'. Indexes como B-tree resolvem isso em O(log n).

Com vetores, o problema é diferente. Você tem um vetor de query (1536 floats) e precisa encontrar os K vetores mais similares entre milhões. A busca “exata” (comparar com todos) é O(n). Com 10 milhões de documentos, cada busca compara 10 milhões de vetores. Inaceitável.

A solução? Approximate Nearest Neighbor (ANN). Aceitar 95-99% de accuracy em troca de velocidade 1000x maior. É o mesmo trade-off que caching: você abre mão de “sempre correto” em troca de “rápido o suficiente”.

HNSW: o algoritmo que você vai encontrar em todo lugar

Hierarchical Navigable Small World (HNSW) é o índice mais usado. Pensa nele como um skip list multi-dimensional.

A ideia:

Estrutura em camadas do HNSWNível 3AMZNível 2ADHMRZNível 1ABDFHJMORVZNível 0ABCDEFGHIJKLMN...

Cada nível é um grafo com conexões entre vetores. Níveis superiores são mais “sparse” (poucos nós, conexões longas). Níveis inferiores são densos (todos os nós, conexões curtas).

Busca: começa no topo (poucos saltos longos pra chegar na região certa), desce nível por nível refinando. Como usar uma estrada principal pra chegar na cidade, depois ruas locais pra chegar no endereço.

Performance:

  • Tempo de busca: O(log n)
  • Memória: O(n × M × d) onde M é número de conexões e d é dimensão
  • Build time: O(n × log n)

HNSW em números reais

VetoresDimensãoMemória (HNSW)Latência p99Recall@10
1M1536~8 GB< 5ms98%
10M1536~80 GB< 10ms97%
100M1536~800 GB< 20ms95%

Percebe o padrão? HNSW mora em memória. 100M vetores de 1536 dimensões precisam de ~800GB de RAM. É por isso que vector databases em escala ficam caros rápido.

IVF: a alternativa disk-friendly

Inverted File Index (IVF) usa uma abordagem diferente. Em vez de grafo, ele particiona o espaço em clusters.

  1. Training: roda K-means pra dividir os vetores em N clusters (ex: 1024)
  2. Busca: identifica os clusters mais próximos da query, busca apenas dentro deles
Espaço vetorial particionado no IVFEspaço vetorial particionadoC1C2C3C4C5C6QQuery Q está perto de C2 e C5.Em vez de buscar em todos os vetores, busca só em C2 e C5 (nprobe=2).

Trade-off: IVF é mais eficiente em disco, mas o parâmetro nprobe (quantos clusters buscar) controla o trade-off accuracy vs velocidade. Menos probes = mais rápido, menos preciso.

Quantização: comprimindo vetores

Se HNSW precisa de muita RAM, quantização reduz isso drasticamente. Em vez de guardar cada dimensão como float32 (4 bytes), comprime pra menos bits.

TipoBytes por dimensãoVetor 1536dPerda de accuracy
Float32 (original)46.1 KB0%
Float1623.0 KB~0%
Int8 (SQ)11.5 KB1-3%
Binary (1 bit)0.125192 bytes10-20%
Product Quantization~0.25-0.5384-768 bytes3-8%

Na prática, Scalar Quantization (int8) dá o melhor custo-benefício. Reduz RAM em 4x com perda mínima de accuracy.

# Azure AI Search: criar índice vetorial com quantização via REST data plane
az rest --method POST \
  --url "https://meu-search.search.windows.net/indexes?api-version=2026-04-01" \
  --skip-authorization-header \
  --headers Content-Type=application/json api-key=$SEARCH_ADMIN_KEY \
  --body '{
    "name": "meu-indice",
    "fields": [
      {"name": "id", "type": "Edm.String", "key": true, "filterable": true},
      {"name": "content", "type": "Edm.String", "searchable": true},
      {
        "name": "embedding",
        "type": "Collection(Edm.Single)",
        "searchable": true,
        "retrievable": false,
        "stored": false,
        "dimensions": 1536,
        "vectorSearchProfile": "meu-perfil"
      }
    ],
    "vectorSearch": {
      "algorithms": [{
        "name": "meu-hnsw",
        "kind": "hnsw",
        "hnswParameters": {
          "m": 4,
          "efConstruction": 400,
          "efSearch": 500,
          "metric": "cosine"
        }
      }],
      "compressions": [{
        "name": "minha-quantizacao",
        "kind": "scalarQuantization",
        "scalarQuantizationParameters": {
          "quantizedDataType": "int8"
        },
        "rescoringOptions": {
          "enableRescoring": true,
          "defaultOversampling": 10,
          "rescoreStorageMethod": "preserveOriginals"
        }
      }],
      "profiles": [{
        "name": "meu-perfil",
        "algorithm": "meu-hnsw",
        "compression": "minha-quantizacao"
      }]
    }
  }'

O bloco rescoringOptions é importante. Busca primeiro com vetores quantizados (rápido), depois recalcula o ranking com vetores originais (preciso). É como usar um CDN pra filtrar e depois ir no origin server pra confirmar.

Comparando soluções: o que usar

SoluçãoTipoMelhor praCuidado com
Azure AI SearchManaged, hybrid (vector + text)RAG com docs, busca semânticaCusto em escala alta
pgvector (PostgreSQL)Extension em DB existenteTimes pequenos, já usam PostgreSQLPerformance > 5M vetores
QdrantDedicado, open-sourceAlta performance, self-hostedOps overhead
PineconeManaged, serverlessEscala sem opsVendor lock-in, custo
Azure Cosmos DB (vector)Multi-model managedJá usa Cosmos, quer adicionar vectorsFeature mais recente
Redis (vector)In-memory, rápidoLatência ultra-baixa, cache de embeddingsRAM cara em escala

pgvector: quando já tem PostgreSQL

Se seu time já roda PostgreSQL, pgvector é a forma mais simples de começar. Adiciona suporte a vetores sem novo serviço.

-- Habilitar extensão
CREATE EXTENSION vector;

-- Criar tabela com coluna de embedding
CREATE TABLE documentos (
  id SERIAL PRIMARY KEY,
  conteudo TEXT,
  embedding vector(1536)
);

-- Criar índice HNSW
CREATE INDEX ON documentos 
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);

-- Buscar os 5 mais similares via prepared statement / driver
-- Passe em $1 um vetor 1536d gerado pelo mesmo modelo de embedding
SELECT id, conteudo,
       1 - (embedding <=> $1::vector) AS similarity
FROM documentos
ORDER BY embedding <=> $1::vector
LIMIT 5;

Limitação: pgvector funciona bem até ~5 milhões de vetores. Depois disso, performance degrada. Se precisa de mais, considere uma solução dedicada.

Métricas de distância: qual usar

Três opções principais. A escolha depende do modelo de embedding que gerou os vetores.

MétricaFórmula (simplificada)Quando usarModelos que usam
CosineÂngulo entre vetoresMais comum, normaliza magnitudeOpenAI, Cohere
Euclidean (L2)Distância geométricaQuando magnitude importaSentence-BERT
Dot ProductMultiplicação diretaVetores já normalizados, mais rápidoQuando pre-normalizado

Na dúvida, use cosine. OpenAI e Azure OpenAI normalizam seus embeddings, então cosine e dot product dão o mesmo resultado. Mas cosine é mais seguro como default.

Operações do dia a dia

Backup e recovery

Vector databases precisam de backup como qualquer outro. Os vetores são dados derivados (gerados a partir de texto por um modelo de embedding), mas re-gerar 10 milhões de embeddings pode levar horas e custar centenas de dólares em API calls.

# Azure AI Search: não tem backup nativo "click-button"
# Estratégia: manter os dados fonte + pipeline de re-indexação

# Exportar uma página de documentos via Search API
az rest --method POST \
  --url "https://meu-search.search.windows.net/indexes/meu-indice/docs/search?api-version=2026-04-01" \
  --skip-authorization-header \
  --headers Content-Type=application/json api-key=$SEARCH_QUERY_KEY \
  --body '{
    "search": "*",
    "top": 1000,
    "skip": 0,
    "select": "id,content"
  }'

Monitoring

Métricas que importam pra vector DB em produção:

  • Query latency (p50, p95, p99): deve ficar < 50ms pra boa UX
  • Index size vs available memory: se o índice não cabe em RAM, performance desaba
  • Recall: % de resultados corretos (monitore via amostras)
  • Indexing throughput: quantos vetores/segundo consegue ingerir
  • Storage utilization: especialmente com quantização
# Azure AI Search: verificar estatísticas do índice
az rest --method GET \
  --url "https://meu-search.search.windows.net/indexes/meu-indice/stats?api-version=2026-04-01" \
  --skip-authorization-header \
  --headers api-key=$SEARCH_ADMIN_KEY \
  --query "{documentCount: documentCount, storageSize: storageSize}"

Scaling patterns

Vertical: mais RAM = mais vetores em HNSW. Mais CPU = buscas paralelas mais rápidas.

Horizontal (sharding): dividir vetores entre múltiplos nós. Cada nó busca no seu subset, results são merged. Azure AI Search faz isso automaticamente com partitions.

Tiered storage: vetores “quentes” (buscados frequentemente) em HNSW na RAM. Vetores “frios” em disco com IVF. Similar a hot/cool/archive tiers em storage.

O que levar pra segunda-feira

  • Vector DB é como um search engine especializado, não um banco relacional. Otimizado pra busca por similaridade, não pra queries complexas.
  • HNSW domina mas come RAM. Quantização (int8) reduz 4x com perda mínima.
  • Escolha de solução: se já tem PostgreSQL e < 5M vetores, pgvector. Se precisa de escala e features de busca, Azure AI Search. Se precisa de controle total, Qdrant self-hosted.
  • Backup é importante mesmo sendo dados derivados. Re-gerar embeddings custa dinheiro e tempo.
  • A métrica que importa é recall, não só latência. Uma busca rápida que retorna resultados irrelevantes é inútil.

No próximo post, vamos juntar embeddings + vector database + LLM no padrão que todo mundo está implementando: RAG (Retrieval-Augmented Generation).

Leitura complementar