9 pontos por GN⁺ 2025-11-04 | 5 comentários | Compartilhar no WhatsApp
  • A extensão pgvector do Postgres oferece suporte à busca por similaridade vetorial, mas existe uma grande diferença entre o nível de demo e o ambiente real de produção
  • Tanto os índices IVFFlat quanto HNSW têm vantagens e desvantagens bem definidas; em especial, o HNSW traz como problema o uso de vários GB de memória na criação do índice e o longo tempo de build
  • A busca em tempo real e a atualização de índices são estruturalmente difíceis e, com inserções e atualizações contínuas, surgem contenção de locks e degradação de desempenho
  • Devido à estratégia de filtragem (Pre/Post) e às limitações do query planner, aparece um equilíbrio instável entre precisão da busca e velocidade
  • É preciso implementar manualmente recursos oferecidos por bancos de dados vetoriais dedicados (Pinecone, Weaviate etc.), o que no fim leva a maior complexidade operacional e aumento de custos

Visão geral das limitações do pgvector

  • O pgvector é uma extensão que adiciona busca por similaridade vetorial ao Postgres e funciona bem em demos simples, mas em ambientes de produção surgem problemas de escalabilidade
  • Muitos posts de blog tratam apenas da instalação e de exemplos simples de consulta, e quase não mencionam os problemas de desempenho, memória e gerenciamento de índices que aparecem em produção

O problema da escolha do índice

  • O pgvector oferece dois tipos de índice: IVFFlat e HNSW
    • IVFFlat: estrutura baseada em clusters; a criação do índice é rápida, mas a configuração do número de clusters afeta fortemente o desempenho e a precisão
      • Como a redistribuição de clusters não é possível, é necessário reconstruir o índice periodicamente
    • HNSW: estrutura de grafo multicamada que oferece precisão e desempenho consistente, mas tem uso de memória muito alto e velocidade lenta na criação do índice
  • Ao criar índices para milhões de vetores, pode haver uso de mais de 10 GB de RAM, o que representa uma ameaça direta à estabilidade do banco de dados em produção

As dificuldades da busca em tempo real

  • Novos dados precisam ficar pesquisáveis imediatamente após a inserção, mas, por causa da própria estrutura de atualização dos índices, é difícil refletir isso em tempo real
    • IVFFlat: novos vetores são adicionados aos clusters existentes e, com o tempo, ocorre desequilíbrio entre clusters → necessidade de rebuild periódico
    • HNSW: durante a inserção, a atualização do grafo causa contenção de locks e carga de memória
  • Durante a reconstrução do índice, é difícil manter a consistência dos dados e garantir a continuidade do serviço
  • Em ambientes de produção, são necessárias várias estratégias de contorno, como staging tables, índices duplos, build offline e eventual consistency

Limitações da filtragem e do query planner

  • Ao combinar filtragem de metadados como status, user_id, category com busca vetorial, a escolha entre Pre-filter vs Post-filter tem grande impacto no desempenho
    • Pre-filter favorece filtros seletivos, mas pode ser lento quando há muitos dados
    • Post-filter é rápido, mas existe a possibilidade de perda de resultados após a filtragem
  • O query planner do Postgres não entende o modelo de custo da similaridade vetorial, e como as estatísticas são imprecisas, acaba gerando planos de execução ineficientes
  • Como resultado, tornam-se necessárias soluções paliativas como CTE, particionamento e reescrita de queries, o que é ineficiente em escala

Comparação com bancos de dados vetoriais dedicados

  • Pinecone, Weaviate, OpenSearch k-NN e outros oferecem por padrão seleção automática da estratégia de filtragem, busca híbrida, indexação em tempo real e escalabilidade horizontal
  • No pgvector, esses recursos precisam ser implementados manualmente, o que leva a complexidade operacional e maior carga de manutenção
  • O pgvectorscale da Timescale oferece StreamingDiskANN, build incremental de índice e melhorias de filtragem, mas
    • não é suportado no AWS RDS e ainda existe a carga adicional de instalar e gerenciar outra extensão

Custos e considerações operacionais

  • Bancos vetoriais dedicados são serviços pagos, mas ao considerar overprovisioning da infraestrutura Postgres, gerenciamento de índices e tempo de engenharia, eles podem na prática sair mais baratos
  • Como exemplo, o Turbopuffer começa em US$ 64 por mês e oferece simplicidade operacional e escalabilidade

Conclusão e recomendações

  • O pgvector é tecnicamente excelente, mas tem muitas restrições em ambientes de produção
  • Pontos principais a considerar ao construir um sistema em produção
    1. A complexidade do gerenciamento de índices e a alta exigência de memória
    2. As limitações do query planner, que levam à ineficiência na filtragem
    3. O custo da indexação em tempo real e a perda de qualidade
    4. A simplificação excessiva dos posts de blog
    5. A razão de existir dos bancos de dados vetoriais dedicados e sua eficiência
  • Em conclusão, a complexidade operacional é maior do que a simplicidade da integração com Postgres, e para a maioria das equipes usar um banco de dados vetorial dedicado é a escolha mais realista

5 comentários

 
kaydash 2025-11-05

Ainda assim, para consultas compostas (embedding + SQL tradicional), não tem nada melhor que o pg_vector.

 
yangeok 2025-11-04

Acho que, para o ecossistema ficar saudável, também precisa haver muitas refutações a essas narrativas de solução universal.

 
ethanhur 2025-11-05

Concordo. Para organizações que já usavam bem o Postgres e estão começando com VectorDB em pequena escala, o pgVector é claramente uma ótima opção, mas parece que, quando o tráfego aumenta — especialmente o tráfego de escrita —, os problemas mencionados pelo autor do texto original acabam se tornando um gargalo.

 
ndrgrd 2025-11-04

Isso mesmo. Afinal, nada é perfeito. Acho que tudo bem dizer algo como "há outras questões mais urgentes", mas não se deve tolerar a ideia de que "o nível atual já é suficiente".

 
GN⁺ 2025-11-04
Comentário no Hacker News
  • Nós, da Discourse, já usamos pgvector em produção em milhares de bancos de dados
    Ele é usado na maioria das visualizações de página, e o recurso Iterative Scans foi adicionado na versão 0.8.0 para melhorar os problemas de pré/pós-filtragem
    Para um serviço único, um banco de dados vetorial dedicado pode até ser mais fácil, mas isso não é uma solução universal

    • Nós usamos quantization de forma agressiva
      Para armazenamento usamos halfvec (float de 16 bits) e, para índices, bit (vetores binários), garantindo tanto custo de armazenamento quanto desempenho
    • Na nossa empresa, Halcyon, lidamos com trilhões de embeddings, e o Postgres não era adequado para essa escala
      Usamos o Vespa para fazer buscas em estilo map-reduce no nível dos nós
      Para fazer algo parecido no Postgres, provavelmente seriam necessários sharding e lógica de aplicação complexa
      Acho que reindexação ou desnormalização de metadados inevitavelmente levariam muito tempo
      Ainda assim, banco de dados vetorial não é solução para tudo, e sistemas como o Vespa, que suportam filtragem relacional, são muito mais eficientes
    • Há muita gente usando pgvector em produção
      Mas o iterative scan não é uma solução fundamental, e sim algo mais próximo de um paliativo
      É preciso entender parâmetros como ef_search e max_search_tuples, e o planner não compreende totalmente o modelo de custo da busca vetorial com filtragem
      No fim, a questão é se você tem capacidade para ajustar manualmente um planejador de consultas inteligente ou se vai usar um serviço especializado nisso
    • Também existe a abordagem de aplicar a filtragem durante a travessia do índice
      O método descrito neste artigo da Microsoft foi implementado pelo Timescale no pgvectorscale
      Esse método pode ser mais eficiente do que uma simples pré/pós-filtragem
    • Fico curioso sobre qual é o caso de uso. Seria por acaso um sistema de busca híbrida combinando palavras-chave + vetor?
  • Nós resolvemos a maior parte dos problemas do pgvector mencionados no post com o VectorChord
    Usando IVF + quantization, ele oferece atualizações 15 vezes mais rápidas do que o HNSW do pgvector
    Com 16 vCPU e 32 GB de memória, é possível indexar 100 milhões de vetores de 768 dimensões em 20 minutos
    É possível reindexar sem perda de dados com CREATE INDEX CONCURRENTLY
    Também oferece suporte a pré/pós-filtragem e busca híbrida baseada em BM25
    Para mais detalhes, veja o blog do VectorChord

    • Se usam quantization e IVF, fico curioso sobre qual é o recall real na prática
    • Temos um cliente operando 3 bilhões de vetores com Postgres + VectorChord + sharding
      O caso pode ser visto neste blog
    • Eu avaliei o VectorChord, mas como não é suportado no RDS, eu teria que adicionar um serviço separado e por isso não consegui adotar
  • A construção de índice consome muita memória, mas isso pode ser controlado com maintenance_work_mem
    A reconstrução do índice pode ser feita com REINDEX CONCURRENTLY, e atualizar HNSW é conceitualmente parecido com atualizar uma B+tree
    Este texto dá a impressão de que não leu a documentação do Postgres direito

    • Mas limitar maintenance_work_mem deixa a indexação mais lenta
      B+tree mexe apenas em páginas log H, enquanto HNSW precisa modificar milhares de vetores
    • Um índice HNSW pode ter de centenas de GB a vários TB
      Para reconstruí-lo, é preciso garantir mais que o dobro da capacidade do banco, e isso também afeta outras cargas de trabalho
      REINDEX CONCURRENTLY também leva muito tempo
      Mesmo que a complexidade de inserção no HNSW seja baixa, o custo constante é alto, então na prática isso pesa bastante
    • Mesmo com configurações como maintenance_work_mem, ocupar vários GB de RAM por horas em produção é arriscado
      REINDEX CONCURRENTLY também usa de 2 a 3 vezes mais disco e afeta o desempenho
      No fim, o problema central não é falta de recursos no Postgres, e sim a complexidade operacional
      Bancos de dados vetoriais dedicados lidam com isso automaticamente, então para equipes pequenas eles são bem mais eficientes
  • O fato de o Turbopuffer começar em US$ 64 por mês ajuda a explicar a popularidade do pgvector
    Se US$ 64 parecer caro, use pgvector; se parecer barato, então seu caso de uso já é complexo o bastante para um banco de dados vetorial dedicado fazer mais sentido

  • Também vi muitos clientes do GCP usando pgvector HNSW em produção
    Mas isso só é realista na faixa de 0 a 10 milhões de vetores
    É preciso considerar ETL, sobrecarga operacional, problemas de consistência etc.
    Se você precisa de transações, busca híbrida e baixa latência, AlloyDB + ScaNN é uma escolha melhor
    (Aliás, eu criei o ScaNN no GCP e hoje lidero o AlloyDB Semantic Search)

    • Como o AlloyDB não é open source, é um produto voltado para outro mercado
  • Meu princípio básico é YAGNI
    Reduzo ao máximo a quantidade de serviços e, se surgir um problema, só então adiciono algo novo
    Se o Postgres for suficiente, sigo com ele; se não for, aí passo a saber exatamente do que preciso

    • Mas essa abordagem muitas vezes sai pela culatra
      Coisas como gravação vetorial em tempo real e combinação de filtros SQL com busca por similaridade parecem detalhes, mas na prática são recursos essenciais
      Quando a escala cresce, essas limitações aparecem de forma crítica
    • Como é difícil trocar de banco de dados depois de escolhido, é melhor ter cuidado desde o início
  • Ao usar modelos de embedding vetorial, há bastante utilidade mesmo sem datasets enormes
    Por exemplo, em casos como busca de documentos ou busca de informações de produtos
    Eu queria uma interface em que, ao gravar documentos como em um sistema de arquivos, o índice fosse atualizado automaticamente
    Por isso serviços como Amazon S3 Vectors(link) parecem interessantes
    Tenho curiosidade sobre experiências reais de uso

    • Você já usou o cocoindex?
      Veja este artigo para um tutorial relacionado
  • Os problemas mencionados já foram resolvidos, e eu prefiro usar PGVector
    Se o Postgres consegue substituir o Kafka e lidar com 100 mil eventos por segundo, então o PGVector também dá conta no lugar de um banco vetorial dedicado como o Chroma
    Link de referência

    • Fico curioso sobre quais problemas exatamente foram resolvidos
  • A maioria dos casos de uso de pgvector é de datasets pequenos, como “chatbot baseado em documentação técnica
    Os dados não mudam com frequência e não há multitenancy, então há menos problemas de filtragem
    Já o Chroma suporta SPANN, SPFresh, busca híbrida e é totalmente open source sob Apache 2.0
    Com cobrança por uso, dá para usar por cerca de US$ 1 por mês

  • O Redis Vector Sets, que desenvolvi ao longo do último ano, resolve esses problemas
    Implementamos HNSW diretamente, permitindo atualizações em tempo real, e a memória é recuperada imediatamente ao excluir
    Suporta inserções de centenas de milhares de ops/sec e buscas de 50 mil ops/sec
    Também suporta quantization por padrão, o que melhora a eficiência de memória
    Tudo está explicado em detalhes no README
    No momento, a funcionalidade de replicação também já foi totalmente testada