Novo: Eficify One em beta aberto. Crie seu primeiro ambiente sem cartão.Conhecer a plataforma →

Vector databases em produção: o que ninguém te conta sobre escolha, storage e queries para RAG

Ilustração técnica de um espaço vetorial tridimensional com pontos conectados por linhas luminosas, representando busca semântica em azul e roxo
CompartilharSeguir

Se você está colocando um vector database em produção e não está pensando em memory footprint, segment compaction e fallback strategy para queries ruins, você está apenas colecionando problemas para o dia seguinte. A verdade é que a maioria dos artigos sobre vector databases para RAG vendem a facilidade de embedding e retrieval sem mostrar a complexidade que emerge quando você tem 50 milhões de vetores, latência P99 abaixo de 100ms e um custo de infraestrutura que compete com o seu banco relacional. Vamos destrinchar os critérios de seleção que realmente importam, os tradeoffs de armazenamento que ninguém explica e os padrões de query que separam um RAG funcional de um que te desperta às 3 da manhã.

A armadilha do demo funciona, produção não

Todo engineer que já montou um protótipo de RAG sabe a sensação: alguns embeddings, uma query, resultados que parecem mágicos. O problema começa quando você precisa escalar. Não estou falando de 10 mil vetores, estou falando de cenários com dezenas de milhões de embeddings, múltiplos filtros por tenant, requisitos de latência P99 abaixo de 100ms e o CFO perguntando por que a conta da cloud triplicou.

A escolha do vector database não é trivial, e os critérios que você vê em comparativos genéricos raramente sobrevivem ao primeiro mês em produção. Vamos ao que importa.

Critérios de seleção que realmente pesam em produção

Não avalie vector databases pelo benchmark de benchmark. Avalie pelo fit com o seu caso concreto.

Scale e footprint de memória

Cada sistema tem um limite prático de vetores que consegue servir com performance aceitável em memória. Pinecone e Qdrant managed chegam a billions de vectors por serverless. Postgres com pgvector começa a apresentar degradação perceptível acima de 5 a 10 milhões de vetores, exigindo sharding manual.

A métrica que importa não é só "quantos vetores cabem", é "quantos vetores cabem por dólar de instância". Um vetor de 1536 dimensões em float32 ocupa 6KB. Em 100 milhões de vetores, isso é 600GB só de dados brutos, sem o overhead dos índices.

Suporte a filtragem híbrida

Se o seu RAG tem escopo por tenant, categoria ou data, você precisa de filtragem por metadata integrada ao índice, não aplicada como postfiltering que desperdiça budget de retrieval.

Qdrant e Weaviate: filtragem por payload com impacto controlável na performance. pgvector: filtragem via WHERE nativo do Postgres, funcional mas sem otimização vetorial. Milvus: segmented filtering com tradeoff entre recall e custo.

Operacionalidade e ecossistema

A escolha entre managed service e selfhosted tem implicações concretas:

Opção Custo mensal (estimativa) Operacionalidade Melhor para
Pinecone US$ 70+ (starter) Zero Times pequenos, rollout rápido
Qdrant Cloud US$ 25+ por GB Mínima Custobenefício, controle parcial
Qdrant selfhosted Infra + ops Alta Compliance, otimização de custo
Milvus on Kubernetes Infra + ops Muito alta Scale extreme, customização
pgvector Infra + ops Média Já tem Postgres, scale pequeno

Tradeoffs de armazenamento que definem custo e performance

O ponto central é: storage e compute para vector search são dominados por duas operações: construção do índice e execução de queries. Cada escolha de algoritmo tem implicações diretas.

HNSW: o default com appetite por memória

Hierarchical Navigable Small World é o algoritmo mais usado por oferecer recall alto (tipicamente 95%+ com tune adequada) com latência subms para datasets que cabem em memória.

Os parâmetros críticos:

M (número de conexões por nó): mais conexões = mais recall, mais memória, construção mais lenta. ef_construction: tamanho da lista de candidatos durante construção. Default de 200 é conservativo demais para production. ef_search: controla a profundidade da busca. ef_construction >= 100 e M entre 16 e 32 são configs razoáveis para produção com 10M+ vetores.

O problema: HNSW não compressa vetores. O índice inteiro vive em memória. Para 100M de vetores de 1536 floats, você precisa de ~720GB só para os dados, sem o índice.

Quantization: o caminho para scale

Product Quantization (PQ) divide cada vetor em subvetores e atribui cada um a um centroid (codebook). O vetor final é representado por um código compacto de poucos bytes.




hnsw_config {
  m = 16                    # conexões por nó (16 a 32 é typical)
  ef_construct = 200        # during indexing
  full_scan_threshold = 10000  # below this, prefer exact scan
}

quantization_config {
  scalar {
    type = int8             # 4x compression vs float32
    quantile = 0.99        # robust to outliers
    always_ram = true       # keep quantized vectors in RAM
  }
}

# Para datasets > 10M vectors, considere product quantization:
# quantization_config {
#   product {
#     compression = 8       # 8 bits per subvector
#     # tradeoff: ~90% memory reduction, ~25% recall loss
#   }
# }

O tradeoff é claro: PQ pode reduzir memory footprint em 8 a 16x com perda de recall entre 2 e 8% dependendo da dimensionalidade e do número de centroids. Para a maioria dos casos de RAG, essa degradação é aceitável frente à economia de custo.

IVF: particionamento antes da busca

Inverted File Index agrupa vetores similares em clusters e busca apenas nos clusters mais relevantes durante query. Isso reduz o número de comparações drasticamente em datasets grandes.

IVFPQ combina particionamento com quantization: primeiro identifica os clusters candidatos, depois compara vetores quantizados dentro deles. É a abordagem mais eficiente para 100M+ vetores.

Diskbacked vs full inmemory

Para datasets que não cabem em RAM, duas estratégias:

Memorymapped files (MMap): o sistema operacional faz paging sob demanda. Latência é maior e variável, mas custo por vetor cai drasticamente. DiskANN e derivados: algoritmos projetados para busca em disco com graph shortcuts que minimizam I/O. Milvus e Qdrant suportam variantes.

Se você tem 1B de vetores e não pode pagar 6TB de RAM, MMap é o caminho. Aceitar latência de 20 a 50ms em vez de 5ms é geralmente aceitável para retrieval assíncrono em RAG.

Padrões de query para RAG que funcionam em produção

Retrieval não termina no vector search. O pipeline completo é mais longo e mais sujeito a falhas do que parece.

flowchart LR
    subgraph INGESTION["INGESTÃO"]
        A["Documentos"]
        B["Chunking"]
        C["Embedding"]
        D["Vector DB"]
    end
    subgraph QUERY["CONSULTA"]
        E["Query"]
        F["Retrieval"]
        G["Reranking"]
        H["LLM"]
        I["Resposta"]
    end
    A -->|docs| B
    B -->|chunks| C
    C -->|vectors| D
    E -->|embed| F
    D -->|context| F
    F -->|topk| G
    G -->|ranked| H
    H -->|response| I
    style A fill:#1e3a5f,stroke:#00d4ff,color:#00d4ff
    style B fill:#1e3a5f,stroke:#00d4ff,color:#00d4ff
    style C fill:#1e3a5f,stroke:#00ff88,color:#00ff88
    style D fill:#1e3a5f,stroke:#00ff88,color:#00ff88
    style E fill:#1e3a5f,stroke:#00d4ff,color:#00d4ff
    style F fill:#1e3a5f,stroke:#00ff88,color:#00ff88
    style G fill:#1e3a5f,stroke:#00ff88,color:#00ff88
    style H fill:#1e3a5f,stroke:#00d4ff,color:#00d4ff
    style I fill:#1e3a5f,stroke:#00d4ff,color:#00d4ff
    style INGESTION fill:#0a1628,stroke:#00d4ff
    style QUERY fill:#0a1628,stroke:#00d4ff
Diagrama de arquitetura RAG

Chunking: a decisão que você não quer acertar por chance

O tamanho do chunk afeta diretamente a qualidade do retrieval. Chunks maiores capturam mais contexto mas diluem a especificidade. Chunks menores são mais específicos mas podem perder contexto.

Chunk size de 512 tokens com overlap de 50 a 100 tokens é um ponto de partida razoável para a maioria dos LLMs. Semantic chunking (chunking baseado em mudança de embedding direction) supera chunking fixo em 15 a 20% de ganho em benchmarks, mas adiciona complexidade de preprocessing. Hierarchical retrieval (buscar segmentos pequenos, expandir para contexto maior antes de enviar ao LLM) é a abordagem mais robusta para documentos longos.

Retrieval híbrido: dense + sparse

Pure vector search falha em exact keyword matching. Sparse embeddings (BM25, SPLADE) capturam matching lexical. A combinação dos dois via Reciprocal Rank Fusion (RRF) supera ambos isolados:

# Reciprocal Rank Fusion  implementação mínima
def rrf(scores_a: dict[str, float], scores_b: dict[str, float], k: int = 60) > dict[str, float]:
    """Combina dois rankings com fusion score.
    
    k=60 é o default do BM25; ajuste para controlar
    penalização de ranks distantes.
    """
    fused = {}
    for doc_id, score in scores_a.items():
        fused[doc_id] = fused.get(doc_id, 0) + 1 / (k + scores_a[doc_id])
    for doc_id, score in scores_b.items():
        fused[doc_id] = fused.get(doc_id, 0) + 1 / (k + scores_b[doc_id])
    return dict(sorted(fused.items(), key=lambda x: x[1], reverse=True))

Reranking: onde você recupera o recall perdido

Depois do retrieval inicial (tipicamente top50 a top100), um crossencoder reranker (Cohere Rerank, BGE Reranker) recalcula a relevância com o query completo, não só a embedding similarity. Isso adiciona 50 a 200ms de latência por query mas pode melhorar MRR@10 em 30 a 40%.

O padrão productionready é: fast vector search (top100) → crossencoder rerank (top10) → contexto para LLM.

Métricas que importam e como monitorálas

Não monitore apenas latência média. Para RAG em produção:

Recall@K (vs ground truth): quantifique quanto você está perdendo para o retrieval ideal. Sem labeled data, isso é impossível de trackar. Latência P99: 1% das queries vai dominar a experiência do usuário se você não otimizar. QPS por dólar: sua real medida de eficiência de custo. Index size vs raw data: se isso passar de 10x, você tem problema de configuração ou está usando M absurdamente alto.

Conclusão: a decisão que você não quer adiar

A escolha do vector database em produção se resume a três dimensões: scale esperado, necessidade de filtragem híbrida e capacidade operacional do seu time.

Para a maioria dos casos:

Scale < 5M vetores, filtragem simples**: pgvector é o atalho mais rápido se você já tem Postgres. Se não tem, Qdrant singlenode. **Scale 5 a 100M, filtragem complexa**: Qdrant ou Milvus com HNSW + quantization. Selfhosted se você tem ops bandwidth. **Scale > 100M ou zero ops: managed service (Pinecone, Qdrant Cloud, Weaviate Cloud).

O erro mais caro que você pode cometer é escolher o vector database antes de ter clareza sobre o padrão de queries (filtragem? híbrido? reranking?) e o volume real de dados. Essas variáveis mudam fundamentalmente o tradeoff entre recall, latência e custo.

Teste com dados reais, queries reais e métricas de retrieval real antes de commit. Prototype com pgvector em duas horas. Escalone quando souber o que está escalando.


Se você está dimensionando uma arquitetura de retrieval vetorial e quer validar tradeoffs antes de travar decisões irreversíveis, a Eficify pode facilitar uma conversa técnica de 30 minutos com um arquiteto especialista.

Fale com um especialista da Eficify

CompartilharSeguir
Bruno Carrilhos

SOBRE O AUTOR

Bruno Carrilhos

CTO · Eficify

Executivo de tecnologia, cofundador da Eficify, com mais de 20 anos de experiência na criação, evolução e sustentação de soluções digitais. Atua nas áreas de desenvolvimento de software, dados, inteligência artificial, cloud computing, cibersegurança e operações de missão crítica. É bacharel em Ciência da Computação, com formação em Ciência de Dados e Inteligência Artificial e pós-graduação em Segurança da Informação.