Módulo 5: Landscape de Vector Databases para AI Engineers
Cápsula 03: Managed vs Self-Hosted
🎯 Objetivo de la cápsula
Entender el trade-off operativo más importante al elegir vector database: ¿servicio managed o infraestructura propia? Y construir un framework de decisión que puedas aplicar a cualquier proveedor.
Esta decisión no es técnica en aislamiento — es una decisión de negocio que afecta velocidad de entrega, costos a largo plazo, control de datos y carga del equipo. Un equipo de 3 personas que elige self-hosted puede terminar dedicando el 40% de su tiempo a operación en lugar de producto. Un equipo enterprise que elige managed puede enfrentar costos inesperados al escalar o restricciones de compliance que no anticipó.
En esta cápsula desglosarás las ventajas, riesgos y costos ocultos de ambos modelos. El objetivo no es que uno sea "mejor" — es que sepas cuál reduce más riesgo para tu contexto específico de equipo, presupuesto y etapa de producto.
Al finalizar esta cápsula:
- ✅ Explicarás ventajas y riesgos concretos de managed y self-hosted
- ✅ Calcularás TCO (Total Cost of Ownership) para ambos modelos
- ✅ Identificarás señales de que elegiste el modelo incorrecto
- ✅ Aplicarás un framework de decisión con criterios ponderados
Tiempo estimado: 20-25 minutos
🏢 Modelo Managed: "Tú construyes RAG, ellos operan la DB"
¿Qué significa managed?
En el modelo managed, el proveedor se encarga de:
- Provisión de infraestructura (servidores, storage, networking)
- Escalado automático (vertical y horizontal)
- Backups y disaster recovery
- Actualizaciones de software y patches de seguridad
- Monitoreo y alertas de infraestructura
- Alta disponibilidad (multi-AZ, failover)
Tú te limitas a interactuar con la API: crear índices, insertar vectores, ejecutar queries.
Proveedores managed principales
| Proveedor | Producto Managed | Modelo de pricing |
|---|---|---|
| Pinecone | Pinecone (solo managed) | Serverless: pay-per-query. Pods: capacidad fija |
| Weaviate | Weaviate Cloud Services (WCS) | Por cluster (sandbox gratuito, Standard, Enterprise) |
| Qdrant | Qdrant Cloud | Por nodo (RAM + storage), free tier disponible |
| Milvus | Zilliz Cloud | Por CU (Compute Unit), free tier disponible |
| ChromaDB | En desarrollo* | No disponible a escala en 2026 |
Ejemplo: Setup managed con Pinecone
from pinecone import Pinecone, ServerlessSpec
pc = Pinecone(api_key="YOUR_API_KEY")
pc.create_index(
name="rag-production",
dimension=1536,
metric="cosine",
spec=ServerlessSpec(
cloud="aws",
region="us-east-1"
)
)
index = pc.Index("rag-production")
index.upsert(
vectors=[
{"id": "doc_1", "values": [0.1, 0.2, ...], "metadata": {"source": "api_docs"}}
],
namespace="v1"
)
results = index.query(
vector=[0.1, 0.2, ...],
top_k=10,
namespace="v1",
include_metadata=True
)
Tiempo desde cero hasta query funcionando: ~5 minutos (signup + API key + código).
Ejemplo: Setup managed con Qdrant Cloud
from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, Distance
client = QdrantClient(
url="https://your-cluster-id.aws.cloud.qdrant.io:6333",
api_key="YOUR_API_KEY"
)
client.create_collection(
collection_name="rag-production",
vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
)
Tiempo desde cero hasta query funcionando: ~10 minutos (signup + crear cluster + API key + código).
Ventajas del modelo managed
| Ventaja | Impacto práctico |
|---|---|
| Zero ops | El equipo dedica 100% del tiempo a producto, no a infra |
| Escalado automático | Picos de tráfico no requieren intervención manual |
| HA incluida | Multi-AZ, failover automático, sin configurar |
| Backups automáticos | Disaster recovery sin runbooks propios |
| Time-to-market | De cero a producción en horas, no semanas |
| SLA contractual | 99.9% o 99.95% respaldado por contrato |
Riesgos del modelo managed
| Riesgo | Impacto potencial |
|---|---|
| Vendor lock-in | Migración costosa si necesitas cambiar (APIs propietarias, formatos de datos) |
| Costo creciente | Pricing escala con volumen/tráfico — puede sorprender al 3x o 10x |
| Control limitado | No puedes tunear index parameters, storage engine, o networking |
| Residencia de datos | Datos en cloud del proveedor — problema para compliance (GDPR, HIPAA, etc.) |
| Dependencia de uptime | Si el proveedor tiene outage, tu RAG se cae |
| Feature pace | Dependes del roadmap del proveedor para nuevas features |
Costo oculto: el "lock-in tax"
Escenario: Startup crece de 500K a 5M vectores en 12 meses
Mes 1-6: Pinecone serverless = ~$70/mes ← "Baratísimo"
Mes 7-12: Pinecone serverless = ~$400/mes ← "Aún razonable"
Mes 13-18: Pinecone serverless = ~$1,500/mes ← "¿Cuánto?!"
Costo de migrar a self-hosted en mes 13:
- 2-3 semanas de engineering time
- Downtime risk durante migración
- Rewriting de código que usa Pinecone SDK
- Testing de performance en nueva infra
"Lock-in tax" = seguir pagando $1,500/mes porque migrar
cuesta más a corto plazo que quedarte.
🖥️ Modelo Self-Hosted: "Tú operas todo"
¿Qué significa self-hosted?
En el modelo self-hosted, tú eres responsable de:
- Provisión de servidores (VMs, Kubernetes, bare metal)
- Configuración de la base vectorial (Docker, Helm charts)
- Escalado manual o semi-automático (réplicas, shards)
- Backups y disaster recovery (cron jobs, scripts, snapshots)
- Actualizaciones de versión (testing, rolling updates)
- Monitoreo y alertas (Prometheus, Grafana, custom dashboards)
- Seguridad de red (firewalls, TLS, access control)
Proveedores self-hosted principales
| Proveedor | Imagen Docker | Complejidad de deploy |
|---|---|---|
| Qdrant | qdrant/qdrant | Baja — un container, sin dependencias |
| Weaviate | semitechnologies/weaviate | Media — modules configurables |
| ChromaDB | chromadb/chroma | Baja — un container, ideal para dev |
| Milvus | milvusdb/milvus | Alta — requiere etcd + MinIO + Pulsar |
Ejemplo: Deploy self-hosted con Qdrant (Docker)
# docker-compose.yml
version: '3.8'
services:
qdrant:
image: qdrant/qdrant:latest
ports:
- "6333:6333" # REST API
- "6334:6334" # gRPC
volumes:
- qdrant_data:/qdrant/storage
environment:
QDRANT__SERVICE__GRPC_PORT: 6334
restart: unless-stopped
deploy:
resources:
limits:
memory: 4G
volumes:
qdrant_data:
docker compose up -d
Tiempo desde cero hasta query funcionando: ~15 minutos (Docker + compose + código).
Ejemplo: Deploy self-hosted con Milvus (Docker Compose)
# docker-compose.yml (Milvus standalone)
version: '3.8'
services:
etcd:
image: quay.io/coreos/etcd:v3.5.5
environment:
ETCD_AUTO_COMPACTION_MODE: revision
ETCD_AUTO_COMPACTION_RETENTION: "1000"
volumes:
- etcd_data:/etcd
minio:
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: minio server /minio_data
volumes:
- minio_data:/minio_data
milvus:
image: milvusdb/milvus:v2.4-latest
command: ["milvus", "run", "standalone"]
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000
ports:
- "19530:19530"
- "9091:9091"
depends_on:
- etcd
- minio
volumes:
- milvus_data:/var/lib/milvus
volumes:
etcd_data:
minio_data:
milvus_data:
Tiempo desde cero: ~30-45 minutos (3 servicios, debugging de conectividad).
Observación crítica: Qdrant requiere 1 container. Milvus requiere 3 (+ Pulsar en modo distribuido = 4). Esta diferencia de complejidad operativa es fundamental para equipos pequeños.
Ventajas del modelo self-hosted
| Ventaja | Impacto práctico |
|---|---|
| Control total | Tunear HNSW params, storage, networking, OS |
| Residencia de datos | Datos en tu infra — compliance GDPR/HIPAA resuelto |
| Sin vendor lock-in | Puedes migrar entre cloud providers sin cambiar DB |
| Optimización de costos | A gran escala, infra propia puede ser 3-5x más barata |
| Customización | Builds custom, plugins, integración con stack existente |
| Predicibilidad | Costos fijos (VMs) vs variables (pay-per-query) |
Riesgos del modelo self-hosted
| Riesgo | Impacto potencial |
|---|---|
| Carga operativa | El equipo gasta 20-40% del tiempo en infra en lugar de producto |
| Incidentes | Tú eres el on-call — a las 3am si se cae, es tu problema |
| Actualizaciones | Testing de nuevas versiones, rolling updates, rollbacks |
| Escalado manual | Agregar nodos, rebalancear shards, capacidad planning |
| Expertise requerido | Necesitas saber Docker, K8s, networking, monitoring |
| HA es tu problema | Configurar replicación, failover, health checks |
Costo oculto: el "ops tax"
Escenario: Equipo de 4 engineers opera Qdrant self-hosted
Infra (3 nodos, 8GB RAM c/u):
AWS EC2: $150/mes × 3 = $450/mes
Operación (promedio mensual):
Mantenimiento rutinario: 8 horas/mes
Incidentes (1 cada 2 meses): 4 horas/mes promediado
Actualizaciones: 4 horas/mes
Monitoreo/alertas: 4 horas/mes
Total: 20 horas/mes
Costo engineering ($80/hora): 20 × $80 = $1,600/mes
"Ops tax" total: $450 + $1,600 = $2,050/mes
vs. Qdrant Cloud managed: ~$600-900/mes
Conclusión: Para este equipo, self-hosted sale MÁS caro
cuando incluyes tiempo del equipo.
📊 TCO: Cómo Calcular el Costo Real
Fórmula de TCO
TCO = Costo Directo + Costo Operativo + Costo de Riesgo
Donde:
Costo Directo = Servicio managed O infra (VMs, storage, networking)
Costo Operativo = Horas del equipo × costo/hora
Costo de Riesgo = Probabilidad de incidente × impacto estimado
Tabla de TCO comparativa (6 meses, 1M vectores, 50 QPS)
| Rubro | Managed (Pinecone) | Self-hosted (Qdrant) |
|---|---|---|
| Servicio / Infra | $2,400 | $2,700 |
| Horas equipo (setup) | 8h = $640 | 40h = $3,200 |
| Horas equipo (ops mensual) | 2h × 6 = $960 | 20h × 6 = $9,600 |
| Incidentes estimados | 0 (SLA) | 2 × 8h = $1,280 |
| TCO 6 meses | $4,000 | $16,780 |
Pero... el cruce de costos existe
Costo mensual ($)
│
3000 │ Self-hosted ────────
│ /
2000 │ / Managed ──────────────
│ / /
1000 │──────────/────────/
│ ↑
│ Punto de cruce
│ (~5-10M vectores)
└──────────────────────────────── Vectores
1M 5M 10M 50M
A partir de ~5-10M vectores con tráfico alto,
self-hosted empieza a ser más barato (si el equipo
ya tiene expertise operativo).
Regla de decisión por TCO
def recomendar_modelo(vectores_millones, tiene_devops, meses_deadline):
"""Framework simplificado de decisión managed vs self-hosted."""
if meses_deadline <= 2:
return "MANAGED — prioridad es time-to-market"
if not tiene_devops:
return "MANAGED — sin equipo de operación, self-hosted es riesgo alto"
if vectores_millones < 1:
return "MANAGED — a esta escala el costo de infra es similar, ops no justifica"
if vectores_millones > 10 and tiene_devops:
return "SELF-HOSTED — a esta escala, ahorro de infra supera costo de ops"
return "EVALUAR — zona gris, hacer cálculo de TCO detallado"
print(recomendar_modelo(vectores_millones=0.5, tiene_devops=False, meses_deadline=1))
# → "MANAGED — prioridad es time-to-market"
print(recomendar_modelo(vectores_millones=15, tiene_devops=True, meses_deadline=6))
# → "SELF-HOSTED — a esta escala, ahorro de infra supera costo de ops"
print(recomendar_modelo(vectores_millones=3, tiene_devops=True, meses_deadline=4))
# → "EVALUAR — zona gris, hacer cálculo de TCO detallado"
🧭 Framework de Decisión: 5 Criterios Ponderados
El proceso
- Define los 5 criterios.
- Asigna peso a cada uno (1-5) según prioridad de tu proyecto.
- Puntúa cada modelo (1-5) para cada criterio.
- Multiplica peso × score.
- Suma totales y compara.
Ejemplo completo
Contexto: Startup de 6 personas, RAG para soporte técnico, 800K vectores, sin DevOps dedicado, necesita SLA 99.9%.
| Criterio | Peso | Managed | Self-hosted | Managed Pond. | Self-hosted Pond. |
|---|---|---|---|---|---|
| Time-to-market | 5 | 5 | 2 | 25 | 10 |
| Control de datos | 2 | 3 | 5 | 6 | 10 |
| Costo total (6 meses) | 3 | 3 | 4 | 9 | 12 |
| Capacidad operativa | 5 | 5 | 2 | 25 | 10 |
| Escala futura | 3 | 4 | 4 | 12 | 12 |
| Total | 77 | 54 |
Resultado: Managed gana por 23 puntos → la recomendación es clara.
Otro ejemplo: Enterprise con equipo de plataforma
Contexto: Empresa de 200 personas, equipo de plataforma de 8, 20M vectores, requisitos GDPR estrictos.
| Criterio | Peso | Managed | Self-hosted | Managed Pond. | Self-hosted Pond. |
|---|---|---|---|---|---|
| Time-to-market | 2 | 5 | 3 | 10 | 6 |
| Control de datos | 5 | 2 | 5 | 10 | 25 |
| Costo total (12 meses) | 4 | 2 | 4 | 8 | 16 |
| Capacidad operativa | 3 | 5 | 4 | 15 | 12 |
| Escala futura | 5 | 3 | 5 | 15 | 25 |
| Total | 58 | 84 |
Resultado: Self-hosted gana por 26 puntos → GDPR y escala dominan la decisión.
⚠️ Señales de que Elegiste el Modelo Incorrecto
Señales de que self-hosted fue mala idea
🚩 El equipo gasta > 30% del tiempo en operación de la DB
🚩 Llevas 3+ meses sin deployar features de producto nuevas
🚩 Has tenido > 2 incidentes graves en 6 meses
🚩 El equipo no puede tomar vacaciones sin riesgo operativo
🚩 Las actualizaciones de versión se posponen indefinidamente
Acción: Evalúa migrar a managed. Calcula cuánto cuesta la migración vs. cuánto pierdes en features no entregadas.
Señales de que managed fue mala idea
🚩 El costo mensual creció > 3x en los últimos 6 meses
🚩 Necesitas una feature que el proveedor no soporta (y no está en roadmap)
🚩 Compliance requiere datos on-premise y el proveedor no lo ofrece
🚩 La latencia del proveedor no baja de tu SLA y no puedes tunear
🚩 El proveedor tuvo outages que afectaron tu SLA comprometido
Acción: Planifica migración a self-hosted. Define runway (cuántos meses puedes seguir pagando) y usa ese tiempo para preparar infra.
🔄 Estrategia Híbrida: Lo Mejor de Ambos Mundos
Patrón: "Start Managed, Graduate to Self-Hosted"
Fase 1 (Mes 1-6): Managed
├── Validar producto rápido
├── Iterar en RAG sin carga operativa
└── Definir métricas de éxito
Fase 2 (Mes 7-9): Preparar migración
├── Evaluar TCO a 12 meses
├── Prototipar self-hosted en staging
└── Documentar runbooks de operación
Fase 3 (Mes 10+): Self-hosted
├── Migrar con dual-write (ambos activos)
├── Validar latencia y accuracy
└── Cortar tráfico gradualmente
Código: Abstracción para facilitar migración
from abc import ABC, abstractmethod
from typing import Any
class VectorStore(ABC):
"""Interfaz común para facilitar migración entre proveedores."""
@abstractmethod
def upsert(self, id: str, vector: list[float], metadata: dict) -> None:
pass
@abstractmethod
def query(self, vector: list[float], top_k: int, filters: dict | None = None) -> list[dict]:
pass
@abstractmethod
def delete(self, id: str) -> None:
pass
class PineconeStore(VectorStore):
def __init__(self, index_name: str, api_key: str):
from pinecone import Pinecone
self.index = Pinecone(api_key=api_key).Index(index_name)
def upsert(self, id: str, vector: list[float], metadata: dict) -> None:
self.index.upsert(vectors=[{"id": id, "values": vector, "metadata": metadata}])
def query(self, vector: list[float], top_k: int, filters: dict | None = None) -> list[dict]:
results = self.index.query(vector=vector, top_k=top_k, filter=filters, include_metadata=True)
return [{"id": m.id, "score": m.score, "metadata": m.metadata} for m in results.matches]
def delete(self, id: str) -> None:
self.index.delete(ids=[id])
class QdrantStore(VectorStore):
def __init__(self, collection_name: str, host: str = "localhost", port: int = 6333):
from qdrant_client import QdrantClient
self.client = QdrantClient(host=host, port=port)
self.collection = collection_name
def upsert(self, id: str, vector: list[float], metadata: dict) -> None:
from qdrant_client.models import PointStruct
self.client.upsert(
collection_name=self.collection,
points=[PointStruct(id=id, vector=vector, payload=metadata)]
)
def query(self, vector: list[float], top_k: int, filters: dict | None = None) -> list[dict]:
results = self.client.query_points(
collection_name=self.collection, query=vector, limit=top_k
)
return [{"id": p.id, "score": p.score, "metadata": p.payload} for p in results.points]
def delete(self, id: str) -> None:
from qdrant_client.models import PointIdsList
self.client.delete(collection_name=self.collection, points_selector=PointIdsList(points=[id]))
# Uso: cambiar de proveedor = cambiar una línea
store: VectorStore = PineconeStore("rag-index", api_key="...")
# store: VectorStore = QdrantStore("rag-index", host="qdrant-server")
store.upsert("doc_1", [0.1, 0.2, ...], {"source": "api_docs"})
results = store.query([0.1, 0.2, ...], top_k=5)
Beneficio: La capa de abstracción permite migrar de Pinecone a Qdrant cambiando solo la instanciación — sin tocar el código de RAG.
🔧 Troubleshooting de elección
1. "No sabemos si tendremos escala alta"
Causa: Incertidumbre de producto — normal en fases tempranas.
Solución: Elige por necesidades actuales y define un trigger explícito de revisión. Ejemplo: "Reevaluamos cuando superemos 1M vectores O cuando el costo mensual supere $500". Sin trigger, la reevaluación no ocurre.
2. "Tenemos presupuesto pero no experiencia operativa"
Causa: El equipo es fuerte en desarrollo pero débil en DevOps/SRE.
Solución: Managed reduce riesgo en esta configuración. El costo del servicio será menor que el costo de incidentes y tiempo perdido operando infra sin experiencia. Si quieres construir capacidad operativa, hazlo en staging primero, no en producción.
3. "Queremos control total desde día 1"
Causa: Postura de engineering culture o requisitos de compliance.
Solución: Valida que el equipo puede sostener incidentes y guardias antes de comprometerse. Haz un "fire drill": simula un outage de la DB un viernes a las 5pm. Si no tienen runbook ni persona disponible, self-hosted es un riesgo alto.
4. "El CTO quiere self-hosted, el VP Product quiere managed"
Causa: Diferentes stakeholders optimizan por diferentes variables.
Solución: Usa la tabla de criterios ponderados (sección anterior). Haz que ambos asignen pesos a los 5 criterios ANTES de discutir opciones. Generalmente, alinear pesos resuelve el 80% del debate.
5. "Empezamos managed y ahora el costo es insostenible"
Causa: Crecimiento no anticipado + pricing que escala con uso.
Solución: Planifica migración con dual-write (escribe a ambos sistemas en paralelo durante 2-4 semanas). Compara latencia y accuracy antes de cortar. No migres bajo presión de costo sin validar que self-hosted cumple tus SLAs.
✏️ Ejercicios
Ejercicio 1: Tabla de TCO para tu proyecto
Completa esta tabla con datos reales o estimados de tu proyecto:
| Rubro | Managed | Self-hosted |
|---|---|---|
| Servicio / Infra (6 meses) | $ | $ |
| Setup inicial (horas × costo/hora) | $ | $ |
| Operación mensual (horas × costo/hora × 6) | $ | $ |
| Incidentes estimados (horas × costo/hora) | $ | $ |
| TCO 6 meses | $ | $ |
Guía de estimación
Para managed:
- Servicio: Usa calculadora de Pinecone o Qdrant Cloud. Para 500K vectores, estima $50-150/mes.
- Setup: 4-8 horas (signup, configurar, integrar SDK).
- Operación: 2-4 horas/mes (monitoreo básico, revisar costos).
- Incidentes: 0-2 horas/mes (problemas resueltos por soporte del proveedor).
Para self-hosted:
- Infra: 1-3 VMs (t3.large ~$60/mes cada una). Para 500K vectores, 1 VM es suficiente.
- Setup: 20-40 horas (Docker, networking, backups, monitoring, alertas).
- Operación: 10-20 horas/mes (mantenimiento, actualizaciones, incidentes).
- Incidentes: 4-8 horas/mes promediado (debugging, recovery).
Ejercicio 2: Criterios ponderados
Usa el framework de 5 criterios para tu proyecto actual:
| Criterio | Peso (1-5) | Managed (1-5) | Self-hosted (1-5) | M × Peso | SH × Peso |
|---|---|---|---|---|---|
| Time-to-market | |||||
| Control de datos | |||||
| Costo total | |||||
| Capacidad operativa | |||||
| Escala futura | |||||
| Total |
Solución de referencia (caso: startup 5 personas, 300K vectores)
| Criterio | Peso | Managed | Self-hosted | M × Peso | SH × Peso |
|---|---|---|---|---|---|
| Time-to-market | 5 | 5 | 2 | 25 | 10 |
| Control de datos | 2 | 3 | 5 | 6 | 10 |
| Costo total | 3 | 4 | 3 | 12 | 9 |
| Capacidad operativa | 4 | 5 | 2 | 20 | 8 |
| Escala futura | 3 | 3 | 4 | 9 | 12 |
| Total | 72 | 49 |
Resultado: Managed gana claramente. Para este perfil, self-hosted es un riesgo innecesario.
Ejercicio 3: Identificar señales de alerta
Lee cada escenario y determina si la señal indica que el modelo elegido fue incorrecto:
- Equipo managed gasta $2,000/mes pero solo usa el 15% de la capacidad.
- Equipo self-hosted no ha actualizado la versión de Qdrant en 8 meses.
- Equipo managed tiene latencia p95 de 200ms pero su SLA interno es 100ms.
- Equipo self-hosted tiene 0 incidentes en 6 meses con runbooks documentados.
Solución
-
Señal de alerta managed — Sobreprovisionado. Debería bajar de tier o evaluar serverless. No necesariamente indica modelo incorrecto, pero sí configuración ineficiente.
-
Señal de alerta self-hosted — Deuda técnica acumulada. Las actualizaciones incluyen patches de seguridad y performance. Esto indica que el equipo no tiene capacidad real de operación.
-
Señal de alerta managed — El proveedor no cumple el SLA técnico requerido. Opciones: cambiar de proveedor managed, o migrar a self-hosted con tuning fino de HNSW params.
-
No es señal de alerta — Equipo self-hosted maduro. Operación estable con procesos documentados. Este es el caso ideal para self-hosted.
Ejercicio 4: Diseñar capa de abstracción
Extiende la clase VectorStore (de la sección de estrategia híbrida) para agregar un método health_check() que retorne el estado de la conexión. Implementa para al menos un proveedor.
Solución de referencia
from abc import ABC, abstractmethod
class VectorStore(ABC):
@abstractmethod
def upsert(self, id: str, vector: list[float], metadata: dict) -> None:
pass
@abstractmethod
def query(self, vector: list[float], top_k: int, filters: dict | None = None) -> list[dict]:
pass
@abstractmethod
def delete(self, id: str) -> None:
pass
@abstractmethod
def health_check(self) -> dict:
"""Retorna estado de conexión y métricas básicas."""
pass
class QdrantStore(VectorStore):
def __init__(self, collection_name: str, host: str = "localhost", port: int = 6333):
from qdrant_client import QdrantClient
self.client = QdrantClient(host=host, port=port)
self.collection = collection_name
def health_check(self) -> dict:
try:
info = self.client.get_collection(self.collection)
return {
"status": "healthy",
"vectors_count": info.vectors_count,
"points_count": info.points_count,
"segments": len(info.segments) if hasattr(info, 'segments') else "N/A"
}
except Exception as e:
return {"status": "unhealthy", "error": str(e)}
def upsert(self, id, vector, metadata):
pass # (implementado en sección anterior)
def query(self, vector, top_k, filters=None):
pass
def delete(self, id):
pass
Ejercicio 5: Trigger de reevaluación
Define para tu proyecto:
- Un trigger cuantitativo (número de vectores, costo mensual, QPS).
- Un trigger cualitativo (incidentes, equipo, compliance).
- Un plan de acción cuando se active el trigger.
Solución de referencia
Triggers cuantitativos:
- "Reevaluamos cuando superemos 2M vectores" (escala)
- "Reevaluamos cuando el costo mensual supere $800" (costo)
- "Reevaluamos cuando necesitemos > 100 QPS sostenido" (performance)
Triggers cualitativos:
- "Reevaluamos si tenemos 3+ incidentes en un trimestre" (operación)
- "Reevaluamos si compliance exige residencia de datos on-premise" (regulación)
- "Reevaluamos si contratamos DevOps/SRE dedicado" (capacidad)
Plan de acción:
- Calcular TCO actualizado con datos reales (no estimaciones).
- Prototipar alternativa en staging con datos de producción.
- Comparar latencia p95, accuracy y costo durante 2 semanas.
- Presentar recomendación con datos al equipo.
- Si la migración gana, ejecutar con dual-write durante 4 semanas.
🔗 Conexión con proyecto (Decision Tree)
Esta cápsula alimenta directamente tu decision tree con un nodo de decisión clave:
¿Tiene tu equipo capacidad DevOps/SRE?
├── NO → Managed (Pinecone, Weaviate Cloud, Qdrant Cloud)
│ └── ¿Presupuesto > $500/mes? → Pinecone / Qdrant Cloud
│ └── ¿Presupuesto < $500/mes? → Free tiers / ChromaDB
└── SÍ → ¿Escala > 5M vectores?
├── SÍ → Self-hosted (Milvus o Qdrant)
└── NO → Evaluar TCO managed vs self-hosted
En la siguiente cápsula sumarás el eje de features para RAG (metadata filtering, hybrid search, multi-tenancy) para completar los criterios de decisión.
📝 Resumen
- Managed prioriza velocidad y simplicidad a cambio de control y potencial vendor lock-in.
- Self-hosted da control total pero exige equipo con capacidad operativa real.
- El TCO incluye servicio + horas del equipo + riesgo de incidentes — no solo el precio del servicio.
- Para equipos sin DevOps o en fase temprana, managed reduce riesgo global.
- Para escala > 5-10M vectores con equipo de plataforma, self-hosted puede ser 3-5x más barato.
- La estrategia híbrida (start managed → graduate self-hosted) mitiga riesgos de ambos modelos.
- Una capa de abstracción sobre el SDK del proveedor facilita migración futura.
- Define triggers explícitos de reevaluación — sin trigger, la revisión no ocurre.
📚 Recursos adicionales
- The Twelve-Factor App — Principios para apps cloud-native
- Google SRE Book — Fundamentos de operación en producción
- Pinecone Pricing Calculator — Estimación de costos managed
- Qdrant Cloud Pricing — Comparación de tiers
- Zilliz Cloud Pricing — Managed Milvus pricing
- Weaviate Cloud Pricing — WCS tiers y free sandbox
- AWS EC2 Pricing — Para estimar costos self-hosted
- Vector DB Comparison (Superlinked) — Comparativa actualizada
Tiempo de lectura: 20-25 minutos Siguiente: 04-comparacion-features-rag.md