Pasamos 8 años haciendo que las bases de datos vectoriales fueran más rápidas. Luego nos detuvimos.
El costo importa. Siempre ha importado. Pero hay un orden: solo puedes recortar costos después de haber alcanzado el nivel de rendimiento requerido. Un sistema que es barato pero devuelve resultados incorrectos no es útil. Tampoco lo es uno que no puede mantener la latencia bajo carga.
Milvus se lanzó como código abierto en 2019 con una creencia simple: las bases de datos vectoriales se convertirían en infraestructura de datos fundamental, no en una funcionalidad oculta dentro de una aplicación. Durante más de ocho años, esa creencia nos llevó en una dirección: hacer que la búsqueda vectorial fuera más rápida y más predecible. Compresión de índices, programación de segmentos, ajuste de HNSW, estrategias de precarga — casi todas las optimizaciones importantes apuntaban a lo mismo: llevar los datos a la caché local y buscar más rápido.
Ese trabajo sigue siendo la base. El serving siempre activo es la arquitectura adecuada para cargas de trabajo de búsqueda vectorial de alto QPS y baja latencia. Si una colección se consulta constantemente, mantener los índices residentes en memoria no es un desperdicio — es el costo de ofrecer la experiencia del producto.
Luego nos enfocamos en el costo. El almacenamiento por niveles ayudó — segmentos calientes en memoria, datos fríos en disco y almacenamiento de objetos, ahorros reales. Pero los nodos nunca se apagaban. Para una carga de trabajo que se ejecuta cinco horas al mes, seguías pagando por las otras 715.
Esa brecha es uno de los problemas que el nuevo Zilliz Vector Lakebase está diseñado para resolver. El cambio más grande no es simplemente “hacer que la búsqueda vectorial sea más barata”. Es permitir que los datos semánticos persistentes admitan más de un ciclo de vida de cómputo: serving siempre activo cuando la latencia y el throughput importan, y cómputo bajo demanda cuando los datos necesitan seguir siendo consultables pero no requieren máquinas dedicadas funcionando todo el mes.
La física detrás del modelo de serving siempre activo
La latencia de lectura de S3 es de 20–50 ms por solicitud. El recorrido de grafos HNSW toca cientos de nodos por consulta. Si unes esos dos números, la conclusión es obvia: los índices vectoriales tienen que vivir en memoria local para atender consultas. No es un defecto de diseño — es física.
Para hacerlo concreto: 100M de vectores, 768 dimensiones, float32. Los datos vectoriales sin procesar son ~286 GB; el grafo HNSW (M=48) añade otros ~55 GB en enlaces de vecinos — aproximadamente 340 GB en total.
Modelo tradicional de Milvus QueryNode:
┌──────────────────────────────────────────────────────────────┐
│ Traditional Milvus architecture │
│ │
│ 100M × 768-dim float32 → ~340 GB split across 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 (source of truth) │ │
│ │ 340 GB full dataset │ │
│ └───────────────────────┘ │
│ Collection queryable only when all 340 GB are loaded │
│ Node fails → its segments go dark → reload from S3 │
└──────────────────────────────────────────────────────────────┘
Cada segmento necesita un nodo residente antes de que la colección sea consultable. 340 GB de datos, tres máquinas de 128 GB, funcionando 24/7. Para colecciones consultadas con frecuencia, esto funciona bien. Luego la IA cambió el patrón de demanda.
Los equipos de producto ejecutan experimentos A/B de dos semanas, después de los cuales esos embeddings nunca se vuelven a consultar. En productos SaaS, el 90% de los usuarios no inició sesión la semana pasada. En bases de conocimiento RAG, el 80% de los documentos no se ha recuperado en el último mes. Los datos no son inútiles — podrían consultarse en cualquier momento — pero se consultan raramente. Las bases de datos tradicionales manejan esto con niveles: datos calientes en memoria, datos fríos en disco y carga de páginas bajo demanda. Las bases de datos vectoriales no tenían tal concepto. O cargabas toda la colección, o no era consultable.
Antes de que los embeddings generados por IA se generalizaran, ese binario no era un problema. La mayoría de las cargas de trabajo vectoriales eran sistemas claramente de servicio en línea, donde tenía sentido mantener los índices residentes en memoria, o experimentos offline que podían tolerar pipelines a medida. La IA cambió ese punto intermedio.
Empezamos a ver este cambio en conversaciones con clientes. Los embeddings ya no solo impulsaban chatbots RAG de producción. Un líder global de GPU estaba incrustando datos de conducción autónoma — fotogramas de cámaras, sesiones de conducción, clima, ubicación, marcas de tiempo y otros metadatos — para que los ingenieros pudieran extraer escenarios de conducción raros entre decenas de miles de millones de vectores. Una empresa de tecnología educativa estaba usando búsqueda semántica para detección de plagio multilingüe, donde las cargas de trabajo podían oscilar desde un puñado de documentos hasta más de 10,000 documentos en un lote durante períodos de exámenes.
Este es el contexto de Vector Lakebase. Los equipos de IA están acumulando datos no estructurados que necesitan permanecer persistentes y descubribles, pero el patrón de acceso es desigual. Algunas rutas necesitan servicio continuo. Otras necesitan búsqueda ocasional, exploración o descubrimiento por lotes sobre los mismos datos subyacentes. Tratar todas esas rutas como servicio siempre activo deja demasiada infraestructura inactiva.
Un usuario publicó en nuestro Slack de la comunidad:
"Mis embeddings ya están en S3. ¿Me estás diciendo que necesito pasar tres horas importándolos, mantener tres máquinas con 128 GB de RAM funcionando 24/7 y pagar $24,000 al año — solo para ejecutar consultas ocasionales?"
Tenía razón. El problema no era dónde vivían los datos ni si el índice era lo suficientemente rápido. Estaba pagando precios de datos calientes por un patrón de acceso de datos fríos: 0.7% activo, 100% facturado.
El mercado ya había empezado a demostrar que la economía basada primero en almacenamiento de objetos importaba para las cargas de trabajo vectoriales. Y mantener cómputo sin estado sobre almacenamiento de objetos era una dirección que muchos usuarios querían. Pero la pregunta más difícil para nosotros era cómo llevar ese modelo de costos a una base de datos vectorial completa: con búsqueda filtrada, semántica de base de datos, aislamiento operativo y una ruta que aún se conecte de vuelta con el servicio siempre activo cuando las cargas de trabajo se vuelvan calientes.
Esa es nuestra tesis de Vector Lakebase: mantener los datos semánticos persistentes y dejar que la capa de cómputo se adapte a la carga de trabajo. La búsqueda bajo demanda es una expresión de esa arquitectura. Hacerla bien requirió superar cuatro obstáculos técnicos.
Cuatro barreras para la búsqueda bajo demanda de Lakebase
En el modelo de búsqueda bajo demanda de Lakebase, los QueryNodes se activan bajo demanda, atienden consultas y luego se liberan. Los datos permanecen en almacenamiento de objetos como fuente de verdad. El cómputo escala a cero entre sesiones de consulta. Suena simple, pero hacerlo utilizable requirió abordar la latencia de arranque en frío, el volumen de escaneo, la amplificación de E/S durante la recuperación y los costos fijos del plano de control.
El arranque en frío era demasiado lento
340 GB de índice HNSW. Carga desde S3: más de cuatro minutos. Cuatro minutos de arranque en frío matan cualquier caso de uso bajo demanda. Un usuario lanza una consulta y espera cuatro minutos — eso no es un retraso, es un producto roto.
La solución fue comprimir el índice manteniéndolo utilizable. Construimos cuantización matryoshka de 1+3 bits basada en RabitQ (Gao & Long, 2024). Dos capas, anidadas como muñecas matryoshka.
La capa de 1 bit se carga primero — 13 GB en lugar de 340 GB. La búsqueda se ejecuta sobre ella inmediatamente: RabitQ proporciona un límite de error demostrable en distancias de 1 bit, por lo que puedes podar candidatos de forma segura y garantizar que nada del verdadero top-k se descarte. 85–90% de recall en la primera consulta.
La capa de 3 bits se descarga en segundo plano mientras se ejecuta la búsqueda de 1 bit. Una vez lista, se usa como una pasada de refinamiento: los supervivientes de la etapa de 1 bit se reevalúan con la precisión completa de 1+3 bits. El recall sube a más del 95%. Las dos capas no son alternativas; la interna realiza el filtrado y la externa mejora los resultados.
El rendimiento bruto de cuantización es un cuello de botella a escala. La construcción de índices acelerada por GPU y los kernels de consulta AVX512 / ARM SVE llevan el rendimiento del cálculo de distancias al punto en que la sobrecarga de cuantización es insignificante. Dos mejoras adicionales elevan más el recall: escalado óptimo por vector, donde se minimiza el error de cuantización de cada vector individual en lugar de compartir un factor global; y asignación de bits no uniforme entre dimensiones según la varianza, de modo que las dimensiones densas en información reciben más bits. Ambas reducen directamente el error de cuantización sin aumentar el tamaño del índice.
Primer obstáculo superado. Pero incluso con cuantización completa, escanear 100M vectores sigue siendo costoso.
Escanear 100M vectores
El índice de 1 bit es pequeño, pero el cálculo de distancias sobre 100M vectores sigue siendo lineal. En un modelo bajo demanda, esto se acumula: un tiempo de cómputo mayor significa que el QueryNode permanece residente durante más tiempo, lo que reduce la ventana para la liberación elástica.
Clustering IVF con poda de índice global (el número de buckets escala con el volumen de datos):
┌──────────────────────────────────────────────────────────────┐
│ Índice global + poda IVF │
│ │
│ 100M vectores → clustering IVF (N buckets, N escala con │
│ el volumen de datos) │
│ │
│ ┌───┬───┬───┬───┬───┬───┬───┬───┬─── ··· ───┬───┐ │
│ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ │ N │ │
│ └───┴───┴───┴───┴───┴───┴───┴───┴─── ··· ───┴───┘ │
│ ▲ ▲ ▲ │
│ █ █ █ ← escanear solo ~3% │
│ │
│ Consulta q → encontrar centroides más cercanos → buscar esos buckets │
│ │
│ Datos escaneados: ~3% del total │
│ E/S de S3: traer ~3% de los datos │
│ Cómputo: cálculo de distancia solo en ~3% │
└──────────────────────────────────────────────────────────────┘
IVF no es nuevo, pero dos cosas hacen que el nuestro sea diferente.
Primero, la escala. La mayoría de las implementaciones de IVF se desmoronan a escala de miles de millones de vectores porque construir el índice requiere cargar todo en memoria a la vez. Construimos una construcción de índice distribuida que fragmenta el trabajo de clustering entre nodos: IVF a cualquier escala, incluidos miles de millones de vectores.
Segundo, la interacción con Lakebase. En tiempo de consulta, solo se traen de S3 los buckets relevantes. Sondear ~3% de los clusters, obtener ~3% de los datos, mantener ~3% en la memoria de QueryNode. Un nodo que solo cargó el 3% del conjunto de datos puede recuperarse casi inmediatamente después de que se complete la consulta.
Junto con la cuantización de 1 bit, las dos barreras se combinan: 340 GB → 13 GB (cuantización) → ~400 MB por consulta (poda IVF). El arranque en frío carga solo los centroides de los clusters y los metadatos del índice de 1 bit: 5–10 segundos. Cada consulta posterior obtiene solo los buckets relevantes, no los 13 GB completos.
Segundo obstáculo superado.
Retrieve estaba amplificando la E/S de S3
La búsqueda vectorial devuelve IDs, no datos sin procesar. Obtener vectores originales o campos escalares implica una segunda ronda de lecturas, y en una ruta de consulta nativa de almacenamiento, cada una es una lectura puntual de S3.
El problema era el formato de almacenamiento. Los archivos Parquet estándar usan grupos de filas de 64 MB. Un solo registro vectorial ocupa alrededor de 3 KB. Leerlo significa descargar todo el grupo de filas: 3 KB de datos útiles, 64 MB de E/S real — aproximadamente una amplificación de 20.000x. Tolerable en disco local. Brutal en S3.
Storage V2 abordó la mitad del problema: columnas anchas y estrechas separadas, con vectores y campos escalares almacenados de forma independiente, y grupos de filas reducidos a 1 MB — 64 veces menos amplificación. El inconveniente: la compresión a nivel de bloque de Parquet depende de grupos de filas grandes. Si los reduces, la compresión se degrada; los archivos crecen. Los grupos de filas pequeños y una buena compresión son mutuamente excluyentes en Parquet. Ahí es donde entra Vortex.
Vortex, desarrollado por Spiral y alojado por la Linux Foundation, tiene un diseño totalmente configurable sin una estructura de grupos de filas obligatoria; consultas puntuales directas sobre datos comprimidos mediante codificación anidada Delta → RLE → BitPacking, sin necesidad de descompresión; y selección automática de codificación, basada en el algoritmo BtrBlocks, que equilibra la tasa de compresión, la velocidad de codificación y la velocidad de decodificación.
Benchmarks: 3M de filas, vectores de 128 dimensiones, S3, 256 lectores concurrentes, lote de 10 filas por lectura.
| Métrica | Parquet | Lance | Vortex |
|---|---|---|---|
| Rendimiento de lectura puntual (lecturas/s) | 162 | 464 | 620 |
| Bytes de S3 por lectura (MB) | 9.44 | 0.006 | 0.07 |
| GETs de S3 por fila | ~2 | ~5 | ~2 |
| Rendimiento de escaneo completo (MB/s) | 638 | 730 | 1,548 |
| Rendimiento de escritura (MB/s) | 216 | 247 | 244 |
Parquet descarga 9.44 MB por lectura — el grupo de filas completo. Lance lo reduce a 0.006 MB al leer con granularidad de 512 bytes, pero lo paga en IOPS: ~5 GETs de S3 por fila frente a ~2 para los demás. Vortex queda en 0.07 MB con ~2 GETs por fila — 135 veces menos tráfico que Parquet, sin la penalización de IOPS. El rendimiento de escaneo completo es 2.4 veces mayor que Parquet; las escrituras son comparables.
Tercer obstáculo superado.
Los costos del plano de control no escalaban a cero
Los tres primeros cambios estaban en la ruta de consulta. El cuarto estaba oculto en el plano de control.
Incluso cuando todos los QueryNodes están inactivos, cada instancia de Milvus mantiene su Coordinator y etcd activos. N inquilinos significan N conjuntos. Los QueryNodes podían escalar a cero; esos dos componentes no podían — son con estado y deben permanecer residentes. Con un millón de inquilinos, la sobrecarga del plano de control supera el costo de los QueryNodes.
El plano de control de Lakebase cambia esto de O(N) a O(1):
Milvus tradicional: costo del plano de control O(N)
┌──────────────────────────────────────────────────────────────┐
│ Shared infrastructure │
│ Kafka / Pulsar (shared) Index Pool (shared) │
└──────────────────────────────────────────────────────────────┘
| | |
Tenant A Tenant B Tenant C
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Coordinator │ │ Coordinator │ │ Coordinator │
│ etcd │ │ etcd │ │ etcd │
├──────────────────┤ ├──────────────────┤ ├──────────────────┤
│ QueryNode │ │ QueryNode │ │ QueryNode │
│ (dedicated) │ │ (dedicated) │ │ (dedicated) │
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
└─────────────────────┼─────────────────────┘
↓
┌──────┐
│ S3 │
└──────┘
Lakebase: costo del plano de control O(1)
┌───────────────────────────────────────────────────────────────┐
│ Plano de control compartido (por región) │
│ │
│ ┌──────────────────┐ ┌──────────┐ ┌───────────────────┐ │
│ │ Coordinador │ │ Catálogo │ │ Servicio WAL │ │
│ │ compartido │ │ ≠ etcd │ │ → S3, ≠ Kafka │ │
│ │ │ │ │ │ │ │
│ └──────────────────┘ └──────────┘ └───────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Servicio de índices (pool de compilación GPU) │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────┬─────────────────────────────────┘
┌────────────────────┼─────────────────────┐
NS inquilino A NS inquilino B NS inquilino C
┌────────────┐ ┌────────────┐ ┌───────────┐
│ QueryNode │ │ (inactivo) │ │ QueryNode │
│ QueryNode │ │ escala = 0 │ └────┬──────┘
└──────┬─────┘ └────────────┘ │
└─────────────────────┬─────────────────────┘
↓
┌──────┐
│ S3 │
└──────┘
Lakebase reemplaza cada pieza del antiguo modelo por inquilino. El coordinador se comparte entre inquilinos, reemplazando los coordinadores por inquilino. Catalog reemplaza etcd por instancia y elimina el límite de almacenamiento de 2 GB. WAL Service escribe directamente en S3 sin disco local: rendimiento medido de 750 MB/s, 5,8x Kafka, reemplazando Kafka/Pulsar. Index Service es un pool de compilación GPU compartido entre inquilinos, reemplazando la asignación de GPU por instancia.
"Escalar a cero" deja de significar "los QueryNodes pueden liberarse" y pasa a significar "toda la instancia cuesta casi nada cuando está inactiva."
┌──────────────────────────────────────────────────────────────┐
│ Multiinquilino × Búsqueda bajo demanda Lakebase │
│ │
│ Capa de almacenamiento S3 cómputo (bajo demanda) │
│ ┌──────────────┐ │
│ │Datos inq. A │ ◄──── consulta ──── QueryNode A (activo) │
│ ├──────────────┤ │
│ │Datos inq. B │ (inactivo, sin QueryNode) │
│ ├──────────────┤ │
│ │Datos inq. C │ (inactivo, sin QueryNode) │
│ ├──────────────┤ │
│ │Datos inq. N │ ◄──── consulta ──── QueryNode N (activo) │
│ └──────────────┘ │
│ │
│ 1M inquilinos, 1% activos → el 99% de los datos tiene coste de cómputo cero │
└──────────────────────────────────────────────────────────────┘
Tradicionalmente, la multiinquilinidad significaba compartir un clúster entre inquilinos mediante colecciones o particiones separadas, pero ese clúster tenía techos estrictos: el límite de metadatos de 2 GB de etcd, el rendimiento del coordinador y la capacidad fija de QueryNode. Escalar más allá de esos límites implicaba más clústeres, lo que significaba más sobrecarga.
Lakebase cambia el techo. Catalog reemplaza etcd por un almacén de metadatos escalable, y el coordinador compartido gestiona muchos más inquilinos sin sobrecarga por inquilino. S3 proporciona elasticidad de almacenamiento. El resultado es un único clúster que puede servir a muchos más inquilinos aislados, y solo los inquilinos que reciben consultas activamente consumen cómputo. El resto paga solo por almacenamiento.
Volvamos a ese usuario de Slack
Mismo escenario: 100M de vectores, float32 de 768 dimensiones, 10 consultas al día, un minuto cada una. Activo ~5 horas al mes.
Para esta carga de trabajo, la diferencia importante no es solo dónde viven los bytes. Es si el cómputo tiene que permanecer conectado a esos bytes mientras nadie los está consultando.
Tanto los tiempos de arranque en frío de Milvus autogestionado como el modelo de almacenamiento por niveles de Zilliz Cloud son costos de carga de una sola vez: una vez calientes, las consultas son rápidas. El arranque en frío bajo demanda de Lakebase ocurre al inicio de cada sesión después de que el nodo vuelve a escalar a cero, lo que, para esta carga de trabajo, es básicamente cada vez. 5–10 segundos por sesión es el compromiso por no pagar nada entre sesiones.
El costo autogestionado es principalmente EC2 siempre activo, con 3 × r6g.4xlarge bajo demanda a aproximadamente $2,073/mes, más Kafka. El modelo de almacenamiento por niveles de Zilliz Cloud elimina la carga operativa, pero el modelo de facturación sigue siendo el mismo. La búsqueda bajo demanda de Lakebase cambia el modelo: paga solo por las cinco horas que realmente usas.
| Milvus autogestionado | Modelo de almacenamiento por niveles de Zilliz Cloud | Búsqueda bajo demanda de Lakebase | |
|---|---|---|---|
| Ciclo de vida del cómputo | Siempre activo | Siempre activo | Bajo demanda |
| Costo de cómputo inactivo | Tarifa completa | Tarifa completa | $0 |
| Patrón de arranque en frío | Carga de una sola vez, luego caliente | Carga de una sola vez, luego caliente | 5–10s al inicio de la sesión |
| Mejor ajuste | Cargas de trabajo de serving en caliente | Niveles hot/cold gestionados | Datos semánticos consultados rara vez |
~$240/año. Costo de cómputo cero el 99% del tiempo. Cuatro obstáculos, cuatro capas de cambio.
La física no cambió. S3 sigue siendo 20–50 ms por lectura.
Lo que cambió es el modelo de cómputo alrededor de esa física: el almacenamiento por niveles redujo el costo de almacenar datos más fríos, pero la búsqueda bajo demanda de Lakebase elimina el piso de cómputo siempre activo para cargas de trabajo que están inactivas la mayor parte del tiempo.
Esa brecha importa más que los ahorros. El usuario de Slack que no podía justificar $24,000/año no solo ahorró dinero cuando migró: empezó a indexar más datos porque la búsqueda era lo suficientemente barata como para hacer más de ella. Precio más bajo, más demanda.
Esa es la historia más amplia de Vector Lakebase. Una vez que los datos semánticos pueden persistir independientemente de un único clúster de serving siempre activo, los equipos pueden elegir la forma de cómputo que coincida con la carga de trabajo: serving continuo para rutas calientes, búsqueda bajo demanda para datos consultados rara vez y cómputo por lotes para trabajos de descubrimiento o procesamiento.
Zilliz Vector Lakebase está disponible en vista previa pública
Hemos lanzado la vista previa pública de Zilliz Vector Lakebase— una evolución importante de Zilliz Cloud, de una base de datos vectorial gestionada a una plataforma unificada de datos semánticos, que combina serving vectorial de baja latencia con la apertura, escalabilidad y economía de un data lake.
Capacidades principales de Vector Lakebase:
- Serving por niveles optimizado para diferentes compromisos de rendimiento-costo en tiempo real
- Búsqueda bajo demanda para cargas de trabajo a gran escala o exploratorias sin cómputo siempre activo
- Búsqueda en data lake externo — indexa y busca directamente sobre tus datos de lake existentes
- Búsqueda de espectro completo en vectores, texto, JSON y datos geoespaciales con recuperación híbrida y reranking
- Almacenamiento unificado nativo de lake construido sobre Vortex, un formato abierto con lecturas aleatorias más rápidas y baratas que Lance o Parquet
Si tu stack actual divide el serving y el descubrimiento en sistemas separados, puede valer la pena echar un vistazo a Vector Lakebase. Pruébalo en Zilliz Cloud — los nuevos registros con email de trabajo reciben $100 en créditos gratis — o habla con nosotros sobre tu caso de uso.
Sigue leyendo

Zilliz Cloud Update: Tiered Storage, Business Critical Plan, Cross-Region Backup, and Pricing Changes
This release offers a rebuilt tiered storage with lower costs, a new Business Critical plan for enhanced security, and pricing updates, among other features.

Zilliz Cloud Introduces Advanced BYOC-I Solution for Ultimate Enterprise Data Sovereignty
Explore Zilliz Cloud BYOC-I, the solution that balances AI innovation with data control, enabling secure deployments in finance, healthcare, and education sectors.

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.



