Passamos 8 anos tornando bancos de dados vetoriais mais rápidos. Então paramos.
Custo importa. Sempre importou. Mas há uma ordem: você só pode cortar custos depois de atingir o patamar de desempenho. Um sistema barato, mas que retorna resultados errados, não é útil. Tampouco um que não consegue manter a latência sob carga.
O Milvus foi lançado como código aberto em 2019 com uma crença simples: bancos de dados vetoriais se tornariam infraestrutura de dados essencial, não um recurso escondido dentro de uma aplicação. Por mais de oito anos, essa crença nos levou em uma direção: tornar a busca vetorial mais rápida e mais previsível. Compressão de índices, agendamento de segmentos, ajuste de HNSW, estratégias de prefetch — quase toda grande otimização apontava para a mesma coisa: colocar os dados no cache local e pesquisar mais rápido.
Esse trabalho ainda é a base. O serving sempre ativo é a arquitetura certa para workloads de busca vetorial com alto QPS e baixa latência. Se uma coleção é consultada constantemente, manter índices residentes na memória não é desperdício — é o custo de servir a experiência do produto.
Então nos voltamos para o custo. O armazenamento em camadas ajudou — segmentos quentes na memória, dados frios em disco e armazenamento de objetos, economias reais. Mas os nós nunca desligavam. Para um workload que roda cinco horas por mês, você ainda pagava pelas outras 715.
Essa lacuna é um dos problemas que o novo Zilliz Vector Lakebase foi projetado para resolver. A mudança maior não é simplesmente “tornar a busca vetorial mais barata”. É permitir que dados semânticos persistentes suportem mais de um ciclo de vida de computação: serving sempre ativo quando latência e throughput importam, e computação sob demanda quando os dados precisam permanecer consultáveis, mas não precisam de máquinas dedicadas rodando o mês inteiro.
A física por trás do modelo de serving sempre ativo
A latência de leitura do S3 é de 20–50 ms por requisição. A travessia de grafos HNSW toca centenas de nós por consulta. Junte esses dois números e a conclusão é óbvia: índices vetoriais precisam viver na memória local para servir consultas. Não é uma falha de design — é física.
Para tornar isso concreto: 100M de vetores, 768 dimensões, float32. Os dados vetoriais brutos ocupam ~286 GB; o grafo HNSW (M=48) adiciona mais ~55 GB em links de vizinhança — aproximadamente 340 GB no total.
Modelo tradicional do Milvus QueryNode:
┌──────────────────────────────────────────────────────────────┐
│ Arquitetura tradicional do Milvus │
│ │
│ 100M × 768-dim float32 → ~340 GB divididos em 3 QueryNodes │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ QueryNode 1 │ │ QueryNode 2 │ │ QueryNode 3 │ │
│ │ 128GB RAM │ │ 128GB RAM │ │ 128GB RAM │ │
│ │ + NVMe │ │ + NVMe │ │ + NVMe │ │
│ │ seg 0-99 │ │ seg 100-199 │ │ seg 200-299 │ │
│ │ (~113 GB) │ │ (~113 GB) │ │ (~113 GB) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ load() │ load() │ load() │
│ └─────────────────┼─────────────────┘ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ S3 (fonte da verdade)│ │
│ │ dataset completo 340 GB │ │
│ └───────────────────────┘ │
│ Coleção consultável somente quando todos os 340 GB estão carregados │
│ Nó falha → seus segmentos ficam indisponíveis → recarregar do S3 │
└──────────────────────────────────────────────────────────────┘
Todo segmento precisa de um nó residente antes que a coleção seja consultável. 340 GB de dados, três máquinas de 128 GB, rodando 24/7. Para coleções consultadas com frequência, isso funciona bem. Então a IA mudou o padrão de demanda.
Equipes de produto executam experimentos A/B de duas semanas, após os quais esses embeddings nunca mais são consultados. Em produtos SaaS, 90% dos usuários não fizeram login na semana passada. Em bases de conhecimento RAG, 80% dos documentos não foram recuperados no último mês. Os dados não são inúteis — podem ser consultados a qualquer momento — mas raramente são consultados. Bancos de dados tradicionais lidam com isso com camadas: dados quentes na memória, dados frios em disco e carregamento de páginas sob demanda. Bancos de dados vetoriais não tinham esse conceito. Ou você carregava a coleção inteira, ou ela não podia ser consultada.
Antes de embeddings gerados por IA se tornarem amplamente difundidos, essa escolha binária não era um problema. A maioria das cargas de trabalho vetoriais eram sistemas de atendimento online claramente definidos, nos quais manter índices residentes em memória fazia sentido, ou experimentos offline que podiam tolerar pipelines sob medida. A IA mudou esse meio-termo.
Começamos a ver essa mudança em conversas com clientes. Embeddings não estavam mais apenas impulsionando chatbots RAG em produção. Uma líder global em GPUs estava incorporando dados de direção autônoma — quadros de câmera, sessões de direção, clima, localização, carimbos de data/hora e outros metadados — para que engenheiros pudessem minerar cenários raros de direção em dezenas de bilhões de vetores. Uma empresa de tecnologia educacional estava usando busca semântica para detecção de plágio multilíngue, em que as cargas de trabalho podiam oscilar de um punhado de documentos para mais de 10.000 documentos em um lote durante períodos de exames.
Este é o contexto do Vector Lakebase. Equipes de IA estão acumulando dados não estruturados que precisam permanecer persistentes e descobríveis, mas o padrão de acesso é desigual. Alguns caminhos precisam de atendimento contínuo. Outros precisam de busca ocasional, exploração ou descoberta em lote sobre os mesmos dados subjacentes. Tratar todos esses caminhos como atendimento sempre ativo deixa infraestrutura demais ociosa.
Um usuário publicou em nosso Slack da comunidade:
"Meus embeddings já estão no S3. Você está me dizendo que preciso passar três horas importando-os, manter três máquinas com 128 GB de RAM rodando 24/7 e pagar US$24.000 por ano — só para executar consultas ocasionais?"
Ele estava certo. O problema não era onde os dados estavam ou se o índice era rápido o suficiente. Ele estava pagando preços de dados quentes por um padrão de acesso de dados frios: 0,7% ativo, 100% cobrado.
O mercado já havia começado a provar que a economia baseada em armazenamento de objetos importava para cargas de trabalho vetoriais. E manter computação sem estado sobre armazenamento de objetos era uma direção que muitos usuários desejavam. Mas a pergunta mais difícil para nós era como trazer esse modelo de custo para um banco de dados vetorial completo: com busca filtrada, semântica de banco de dados, isolamento operacional e um caminho que ainda se conecte de volta ao atendimento sempre ativo quando as cargas de trabalho se tornam quentes.
Essa é a nossa tese do Vector Lakebase: manter os dados semânticos persistentes e deixar a camada de computação corresponder à carga de trabalho. A busca sob demanda é uma expressão dessa arquitetura. Fazê-la corretamente exigiu superar quatro obstáculos técnicos.
Quatro barreiras para a busca sob demanda no Lakebase
No modelo de busca sob demanda do Lakebase, QueryNodes sobem sob demanda, atendem consultas e depois são liberados. Os dados permanecem no armazenamento de objetos como fonte da verdade. A computação escala para zero entre sessões de consulta. Isso parece simples, mas torná-lo utilizável exigiu abordar latência de cold start, volume de varredura, amplificação de E/S durante a recuperação e custos fixos do plano de controle.
O cold start era lento demais
340 GB de índice HNSW. Carregamento a partir do S3: mais de quatro minutos. Quatro minutos de cold start acabam com qualquer caso de uso sob demanda. Um usuário dispara uma consulta e espera quatro minutos — isso não é um atraso, é um produto quebrado.
A solução foi comprimir o índice mantendo-o utilizável. Construímos uma quantização matryoshka de 1+3 bits baseada em RabitQ (Gao & Long, 2024). Duas camadas, aninhadas como bonecas matryoshka.
A camada de 1 bit carrega primeiro — 13 GB em vez de 340 GB. A busca roda nela imediatamente: RabitQ fornece um limite de erro comprovável em distâncias de 1 bit, então você pode podar candidatos com segurança e garantir que nada no verdadeiro top-k seja descartado. 85–90% de recall na primeira consulta.
A camada de 3 bits é baixada em segundo plano enquanto a busca de 1 bit está em execução. Quando pronta, é usada como uma passada de refinamento — os sobreviventes da etapa de 1 bit são reclassificados com precisão total de 1+3 bits. O recall vai para 95%+. As duas camadas não são alternativas; a interna realiza a filtragem, e a externa melhora os resultados.
A vazão de quantização bruta é um gargalo em escala. A construção de índice acelerada por GPU e os kernels de consulta AVX512 / ARM SVE elevam a vazão de computação de distância ao ponto em que a sobrecarga de quantização é desprezível. Duas melhorias adicionais elevam mais o recall: escalonamento ótimo por vetor, em que cada vetor tem seu próprio erro de quantização minimizado em vez de compartilhar um fator global; e alocação não uniforme de bits entre dimensões com base na variância, de modo que dimensões densas em informação recebam mais bits. Ambas reduzem diretamente o erro de quantização sem aumentar o tamanho do índice.
Primeiro obstáculo superado. Mas, mesmo com quantização completa, varrer 100M de vetores ainda é caro.
Varrendo 100M de vetores
O índice de 1 bit é pequeno, mas a computação de distância sobre 100M de vetores ainda é linear. Em um modelo sob demanda, isso se acumula: um tempo de computação maior significa que o QueryNode permanece residente por mais tempo, o que reduz a janela para liberação elástica.
Clusterização IVF com poda de índice global (a contagem de buckets escala com o volume de dados):
┌──────────────────────────────────────────────────────────────┐
│ Índice global + poda IVF │
│ │
│ 100M vetores → clusterização IVF (N buckets, N escala com │
│ volume de dados) │
│ │
│ ┌───┬───┬───┬───┬───┬───┬───┬───┬─── ··· ───┬───┐ │
│ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ │ N │ │
│ └───┴───┴───┴───┴───┴───┴───┴───┴─── ··· ───┴───┘ │
│ ▲ ▲ ▲ │
│ █ █ █ ← varre apenas ~3% │
│ │
│ Consulta q → encontra centróides mais próximos → busca nesses buckets │
│ │
│ Dados varridos: ~3% do total │
│ E/S S3: puxa ~3% dos dados │
│ Computação: cálculo de distância em apenas ~3% │
└──────────────────────────────────────────────────────────────┘
IVF não é novidade, mas duas coisas tornam o nosso diferente.
Primeiro, escala. A maioria das implementações de IVF desmorona na escala de bilhões de vetores porque construir o índice exige carregar tudo na memória de uma só vez. Construímos uma construção distribuída de índice que particiona o trabalho de clusterização entre nós — IVF em qualquer escala, incluindo bilhões de vetores.
Segundo, a interação com o Lakebase. No momento da consulta, apenas os buckets relevantes são puxados do S3. Sonda ~3% dos clusters, busca ~3% dos dados, mantém ~3% na memória do QueryNode. Um nó que carregou apenas 3% do conjunto de dados pode ser recuperado quase imediatamente após a conclusão da consulta.
Junto com a quantização de 1 bit, as duas barreiras se combinam: 340 GB → 13 GB (quantização) → ~400 MB por consulta (poda IVF). A inicialização a frio carrega apenas os centróides dos clusters e os metadados do índice de 1 bit — 5–10 segundos. Cada consulta subsequente busca apenas os buckets relevantes, não os 13 GB completos.
Segundo obstáculo superado.
Retrieve estava amplificando a E/S do S3
A busca vetorial retorna IDs, não dados brutos. Obter vetores originais ou campos escalares significa uma segunda rodada de leituras, e em um caminho de consulta nativo de armazenamento, cada uma delas é uma leitura pontual no S3.
O problema era o formato de armazenamento. Arquivos Parquet padrão usam grupos de linhas de 64 MB. Um único registro vetorial tem cerca de 3 KB. Lê-lo significa baixar o grupo de linhas inteiro: 3 KB de dados úteis, 64 MB de E/S real — cerca de 20.000x de amplificação. Tolerável em disco local. Brutal no S3.
Storage V2 resolveu metade disso: colunas largas e estreitas separadas, com vetores e campos escalares armazenados independentemente, e grupos de linhas reduzidos para 1 MB — 64x menos amplificação. O porém: a compressão em nível de bloco do Parquet depende de grandes grupos de linhas. Reduza-os, e a compressão se degrada; os arquivos ficam maiores. Pequenos grupos de linhas e boa compressão são mutuamente exclusivos no Parquet. É aí que entra o Vortex.
O Vortex, desenvolvido pela Spiral e hospedado pela Linux Foundation, tem um layout totalmente configurável, sem estrutura forçada de grupos de linhas; consultas pontuais diretas em dados comprimidos por meio de codificação aninhada Delta → RLE → BitPacking, sem necessidade de descompressão; e seleção automática de codificação, baseada no algoritmo BtrBlocks, que equilibra taxa de compressão, velocidade de codificação e velocidade de decodificação.
Benchmarks: 3M de linhas, vetores de 128 dimensões, S3, 256 leitores simultâneos, lote de 10 linhas por leitura.
| Métrica | Parquet | Lance | Vortex |
|---|---|---|---|
| Vazão de leitura pontual (leituras/s) | 162 | 464 | 620 |
| Bytes do S3 por leitura (MB) | 9.44 | 0.006 | 0.07 |
| GETs do S3 por linha | ~2 | ~5 | ~2 |
| Vazão de varredura completa (MB/s) | 638 | 730 | 1,548 |
| Vazão de escrita (MB/s) | 216 | 247 | 244 |
O Parquet baixa 9.44 MB por leitura — o grupo de linhas inteiro. O Lance reduz isso para 0.006 MB lendo em granularidade de 512 bytes, mas paga por isso em IOPS: ~5 GETs do S3 por linha vs. ~2 para os outros. O Vortex fica em 0.07 MB com ~2 GETs por linha — 135x menos tráfego que o Parquet, sem a penalidade de IOPS. A vazão de varredura completa é 2.4x maior que a do Parquet; as escritas são comparáveis.
Terceiro obstáculo superado.
Os custos do plano de controle não escalavam para zero
As três primeiras mudanças foram no caminho de consulta. A quarta estava escondida no plano de controle.
Mesmo quando todos os QueryNodes estão ociosos, cada instância do Milvus mantém seu Coordinator e etcd ativos. N tenants significa N conjuntos. Os QueryNodes podiam escalar para zero; esses dois componentes não podiam — eles são stateful e precisam permanecer residentes. Com um milhão de tenants, a sobrecarga do plano de controle supera o custo dos QueryNodes.
O plano de controle do Lakebase muda isso de O(N) para O(1):
Milvus tradicional: custo do plano de controle O(N)
┌──────────────────────────────────────────────────────────────┐
│ Infraestrutura compartilhada │
│ Kafka / Pulsar (compartilhado) Index Pool (compartilhado) │
└──────────────────────────────────────────────────────────────┘
| | |
Tenant A Tenant B Tenant C
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Coordinator │ │ Coordinator │ │ Coordinator │
│ etcd │ │ etcd │ │ etcd │
├──────────────────┤ ├──────────────────┤ ├──────────────────┤
│ QueryNode │ │ QueryNode │ │ QueryNode │
│ (dedicado) │ │ (dedicado) │ │ (dedicado) │
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
└─────────────────────┼─────────────────────┘
↓
┌──────┐
│ S3 │
└──────┘
Lakebase: custo do plano de controle O(1)
┌───────────────────────────────────────────────────────────────┐
│ Plano de controle compartilhado (por região) │
│ │
│ ┌──────────────────┐ ┌──────────┐ ┌───────────────────┐ │
│ │ Shared │ │ Catalog │ │ WAL Service │ │
│ │ Coordinator │ │ ≠ etcd │ │ → S3, ≠ Kafka │ │
│ │ │ │ │ │ │ │
│ └──────────────────┘ └──────────┘ └───────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Index Service (Pool de Compilação de GPU) │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────┬─────────────────────────────────┘
┌────────────────────┼─────────────────────┐
NS do Tenant A NS do Tenant B NS do Tenant C
┌────────────┐ ┌────────────┐ ┌───────────┐
│ QueryNode │ │ (ocioso) │ │ QueryNode │
│ QueryNode │ │ escala = 0 │ └────┬──────┘
└──────┬─────┘ └────────────┘ │
└─────────────────────┬─────────────────────┘
↓
┌──────┐
│ S3 │
└──────┘
O Lakebase substitui cada parte do antigo modelo por tenant. O coordinator é compartilhado entre tenants, substituindo coordinators por tenant. O Catalog substitui o etcd por instância e remove o limite de armazenamento de 2 GB. O WAL Service grava diretamente no S3 sem disco local — throughput medido de 750 MB/s, 5,8x Kafka — substituindo Kafka/Pulsar. O Index Service é um pool de compilação de GPU compartilhado entre tenants, substituindo a alocação de GPU por instância.
"Escalar para zero" deixa de significar "QueryNodes podem ser liberados" e passa a significar "a instância inteira custa quase nada quando ociosa."
┌──────────────────────────────────────────────────────────────┐
│ Multi-tenant × Busca sob demanda do Lakebase │
│ │
│ Camada de armazenamento S3 computação (sob demanda) │
│ ┌──────────────┐ │
│ │dados Tenant A│ ◄──── consulta ──── QueryNode A (ativo) │
│ ├──────────────┤ │
│ │dados Tenant B│ (ocioso, sem QueryNode) │
│ ├──────────────┤ │
│ │dados Tenant C│ (ocioso, sem QueryNode) │
│ ├──────────────┤ │
│ │dados Tenant N│ ◄──── consulta ──── QueryNode N (ativo) │
│ └──────────────┘ │
│ │
│ 1M tenants, 1% ativos → 99% dos dados têm custo computacional zero │
└──────────────────────────────────────────────────────────────┘
Tradicionalmente, multi-tenancy significava compartilhar um cluster entre tenants por meio de collections ou partitions separadas — mas esse cluster tinha tetos rígidos: o limite de metadados de 2 GB do etcd, o throughput do coordinator e a capacidade fixa de QueryNode. Escalar além desses limites significava mais clusters, o que significava mais overhead.
O Lakebase muda o teto. O Catalog substitui o etcd por um armazenamento de metadados escalável, e o coordinator compartilhado lida com muito mais tenants sem overhead por tenant. O S3 oferece elasticidade de armazenamento. O resultado é um único cluster que pode atender a muito mais tenants isolados — e apenas os tenants que estão recebendo consultas ativamente consomem computação. O restante paga apenas pelo armazenamento.
Voltando àquele usuário do Slack
Mesmo cenário: 100M vetores, float32 de 768 dimensões, 10 consultas por dia, um minuto cada. Ativo ~5 horas por mês.
Para essa carga de trabalho, a diferença importante não é apenas onde os bytes ficam. É se a computação precisa permanecer vinculada a esses bytes enquanto ninguém os consulta.
Tanto os tempos de cold start do Milvus auto-hospedado quanto o modelo de armazenamento em camadas da Zilliz Cloud são custos de carregamento únicos — uma vez aquecidos, as consultas são rápidas. O cold start sob demanda do Lakebase ocorre no início de cada sessão depois que o nó escala de volta para zero, o que, para essa carga de trabalho, é essencialmente toda vez. 5–10 segundos por sessão é a contrapartida por não pagar nada entre as sessões.
O custo auto-hospedado é principalmente EC2 sempre ativo, com 3 × r6g.4xlarge sob demanda a aproximadamente $2.073/mês, mais Kafka. O modelo de armazenamento em camadas da Zilliz Cloud remove o peso operacional, mas o modelo de cobrança permanece o mesmo. A busca sob demanda do Lakebase muda o modelo: pague apenas pelas cinco horas que você realmente usa.
| Milvus auto-hospedado | Modelo de Armazenamento em Camadas da Zilliz Cloud | Busca Sob Demanda do Lakebase | |
|---|---|---|---|
| Ciclo de vida da computação | Sempre ativa | Sempre ativa | Sob demanda |
| Custo de computação ociosa | Tarifa integral | Tarifa integral | $0 |
| Padrão de cold start | Carregamento único, depois aquecido | Carregamento único, depois aquecido | 5–10s no início da sessão |
| Melhor adequação | Cargas de trabalho de serving quentes | Camadas quente/fria gerenciadas | Dados semânticos raramente consultados |
~$240/ano. Custo de computação zero 99% do tempo. Quatro obstáculos, quatro camadas de mudança.
A física não mudou. O S3 ainda leva 20–50 ms por leitura.
O que mudou é o modelo de computação em torno dessa física: o armazenamento em camadas reduziu o custo de armazenar dados mais frios, mas a busca sob demanda do Lakebase remove o piso de computação sempre ativa para cargas de trabalho que ficam ociosas na maior parte do tempo.
Essa lacuna importa mais do que a economia. O usuário do Slack que não conseguia justificar $24.000/ano não apenas economizou dinheiro quando migrou — ele começou a indexar mais dados porque a busca ficou barata o suficiente para fazer mais dela. Preço menor, mais demanda.
Essa é a história maior do Vector Lakebase. Uma vez que os dados semânticos podem persistir independentemente de um único cluster de serving sempre ativo, as equipes podem escolher o formato de computação que corresponde à carga de trabalho: serving contínuo para caminhos quentes, busca sob demanda para dados raramente consultados e computação em lote para tarefas de descoberta ou processamento.
Zilliz Vector Lakebase está disponível em preview público
Lançamos o preview público do Zilliz Vector Lakebase— uma grande evolução da Zilliz Cloud, de um banco de dados vetorial gerenciado para uma plataforma unificada de dados semânticos, combinando serving vetorial de baixa latência com a abertura, escalabilidade e economia de um data lake.
Principais capacidades do Vector Lakebase:
- Serving em camadas otimizado para diferentes compromissos entre desempenho em tempo real e custo
- Busca sob demanda para cargas de trabalho em grande escala ou exploratórias sem computação sempre ativa
- Busca em data lake externo — indexe e busque diretamente sobre seus dados de lake existentes
- Busca de espectro completo em vetores, texto, JSON e dados geoespaciais com recuperação híbrida e reranking
- Armazenamento unificado lake-native construído sobre Vortex, um formato aberto com leituras aleatórias mais rápidas e baratas do que Lance ou Parquet
Se sua stack atual separa serving e descoberta em sistemas distintos, talvez valha a pena conhecer o Vector Lakebase. Experimente no Zilliz Cloud — novos cadastros com e-mail corporativo recebem $100 em créditos gratuitos — ou fale conosco sobre seu caso de uso.
Continue lendo

Will Amazon S3 Vectors Kill Vector Databases—or Save Them?
AWS S3 Vectors aims for 90% cost savings for vector storage. But will it kill vectordbs like Milvus? A deep dive into costs, limits, and the future of tiered storage.

Vector Databases vs. Time Series Databases
Use a vector database for similarity search and semantic relationships; use a time series database for tracking value changes over time.

Why Deepseek is Waking up AI Giants Like OpenAI And Why You Should Care
Discover how DeepSeek R1's open-source AI model with superior reasoning capabilities and lower costs is disrupting the AI landscape and challenging tech giants like OpenAI.



