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

ProveedorProducto ManagedModelo de pricing
PineconePinecone (solo managed)Serverless: pay-per-query. Pods: capacidad fija
WeaviateWeaviate Cloud Services (WCS)Por cluster (sandbox gratuito, Standard, Enterprise)
QdrantQdrant CloudPor nodo (RAM + storage), free tier disponible
MilvusZilliz CloudPor CU (Compute Unit), free tier disponible
ChromaDBEn 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

VentajaImpacto práctico
Zero opsEl equipo dedica 100% del tiempo a producto, no a infra
Escalado automáticoPicos de tráfico no requieren intervención manual
HA incluidaMulti-AZ, failover automático, sin configurar
Backups automáticosDisaster recovery sin runbooks propios
Time-to-marketDe cero a producción en horas, no semanas
SLA contractual99.9% o 99.95% respaldado por contrato

Riesgos del modelo managed

RiesgoImpacto potencial
Vendor lock-inMigración costosa si necesitas cambiar (APIs propietarias, formatos de datos)
Costo crecientePricing escala con volumen/tráfico — puede sorprender al 3x o 10x
Control limitadoNo puedes tunear index parameters, storage engine, o networking
Residencia de datosDatos en cloud del proveedor — problema para compliance (GDPR, HIPAA, etc.)
Dependencia de uptimeSi el proveedor tiene outage, tu RAG se cae
Feature paceDependes 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

ProveedorImagen DockerComplejidad de deploy
Qdrantqdrant/qdrantBaja — un container, sin dependencias
Weaviatesemitechnologies/weaviateMedia — modules configurables
ChromaDBchromadb/chromaBaja — un container, ideal para dev
Milvusmilvusdb/milvusAlta — 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

VentajaImpacto práctico
Control totalTunear HNSW params, storage, networking, OS
Residencia de datosDatos en tu infra — compliance GDPR/HIPAA resuelto
Sin vendor lock-inPuedes migrar entre cloud providers sin cambiar DB
Optimización de costosA gran escala, infra propia puede ser 3-5x más barata
CustomizaciónBuilds custom, plugins, integración con stack existente
PredicibilidadCostos fijos (VMs) vs variables (pay-per-query)

Riesgos del modelo self-hosted

RiesgoImpacto potencial
Carga operativaEl equipo gasta 20-40% del tiempo en infra en lugar de producto
IncidentesTú eres el on-call — a las 3am si se cae, es tu problema
ActualizacionesTesting de nuevas versiones, rolling updates, rollbacks
Escalado manualAgregar nodos, rebalancear shards, capacidad planning
Expertise requeridoNecesitas saber Docker, K8s, networking, monitoring
HA es tu problemaConfigurar 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)

RubroManaged (Pinecone)Self-hosted (Qdrant)
Servicio / Infra$2,400$2,700
Horas equipo (setup)8h = $64040h = $3,200
Horas equipo (ops mensual)2h × 6 = $96020h × 6 = $9,600
Incidentes estimados0 (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

  1. Define los 5 criterios.
  2. Asigna peso a cada uno (1-5) según prioridad de tu proyecto.
  3. Puntúa cada modelo (1-5) para cada criterio.
  4. Multiplica peso × score.
  5. 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%.

CriterioPesoManagedSelf-hostedManaged Pond.Self-hosted Pond.
Time-to-market5522510
Control de datos235610
Costo total (6 meses)334912
Capacidad operativa5522510
Escala futura3441212
Total7754

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.

CriterioPesoManagedSelf-hostedManaged Pond.Self-hosted Pond.
Time-to-market253106
Control de datos5251025
Costo total (12 meses)424816
Capacidad operativa3541512
Escala futura5351525
Total5884

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:

RubroManagedSelf-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:

CriterioPeso (1-5)Managed (1-5)Self-hosted (1-5)M × PesoSH × Peso
Time-to-market
Control de datos
Costo total
Capacidad operativa
Escala futura
Total
Solución de referencia (caso: startup 5 personas, 300K vectores)
CriterioPesoManagedSelf-hostedM × PesoSH × Peso
Time-to-market5522510
Control de datos235610
Costo total343129
Capacidad operativa452208
Escala futura334912
Total7249

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:

  1. Equipo managed gasta $2,000/mes pero solo usa el 15% de la capacidad.
  2. Equipo self-hosted no ha actualizado la versión de Qdrant en 8 meses.
  3. Equipo managed tiene latencia p95 de 200ms pero su SLA interno es 100ms.
  4. Equipo self-hosted tiene 0 incidentes en 6 meses con runbooks documentados.
Solución
  1. Señal de alerta managed — Sobreprovisionado. Debería bajar de tier o evaluar serverless. No necesariamente indica modelo incorrecto, pero sí configuración ineficiente.

  2. 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.

  3. 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.

  4. 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:

  1. Un trigger cuantitativo (número de vectores, costo mensual, QPS).
  2. Un trigger cualitativo (incidentes, equipo, compliance).
  3. 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:

  1. Calcular TCO actualizado con datos reales (no estimaciones).
  2. Prototipar alternativa en staging con datos de producción.
  3. Comparar latencia p95, accuracy y costo durante 2 semanas.
  4. Presentar recomendación con datos al equipo.
  5. 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


Tiempo de lectura: 20-25 minutos Siguiente: 04-comparacion-features-rag.md