← SCRAM AI Lab

Tutoriales

pgvector para RAG en producción mexicana

Guía técnica para implementar pgvector en producción para sistemas RAG en México: reducción de costos, latencia, índices HNSW y cumplimiento regulatorio local.

May 21, 2026

506 lecturas

pgvector para RAG en producción mexicana

El costo escondido de no usar tu Postgres

Si ya corres Postgres en producción para datos transaccionales (usuarios, deals, transacciones), pagar $70-$300 al mes adicionales por Pinecone o Weaviate para vectores que se relacionan con esos mismos datos es ineficiente. pgvector lleva los embeddings a la misma DB y los une por SQL nativo a tus filas de negocio. En SCRAM corremos pgvector sobre el mismo Postgres del CRM en una GCP e2-standard-4 (4 vCPU, 16GB), sin servicio adicional, sin cuenta nueva, sin latencia de red entre dos sistemas. Costo marginal: $0/mes.

¿Conviene migrar de un vector database dedicado a pgvector en México?

Sí, conviene si manejas menos de cinco millones de vectores y requieres gobernanza estricta sobre tus datos dentro de la infraestructura que ya operas. Al consolidar metadatos y vectores en una sola base relacional, eliminas saltos de red externos hacia servicios administrados foráneos, mitigas riesgos de sincronización transaccional y reduces de golpe la complejidad operativa de tu arquitectura de software.

Cumplimiento y soberanía de datos para empresas mexicanas

En sectores regulados en México como fintech, salud y seguros, la Ley Federal de Protección de Datos Personales en Posesión de los Particulares (LFPDPPP) impone lineamientos severos sobre transferencias internacionales y custodia de información sensible. Al utilizar bases de datos vectoriales SaaS alojadas exclusivamente en regiones de Estados Unidos o Europa, muchos equipos caen en incumplimiento involuntario al exportar fragmentos de contratos, historiales clínicos o datos fiscales.

Mantener los embeddings y su contenido textual en tu propio cluster de PostgreSQL dentro de tu VPC privada (en GCP, AWS o servidores dedicados locales) simplifica drásticamente las auditorías del INAI y la Comisión Nacional Bancaria y de Valores (CNBV). La seguridad perimetral, las llaves de cifrado en reposo (KMS) y las políticas de acceso por rol (RLS) se administran en una sola capa ya validada por tu equipo de ciberseguridad.

Cuándo NO uses pgvector

  • Más de ~10-20M de vectores: el índice HNSW empieza a comer RAM agresivamente. A esas escalas, un servicio especializado paga.
  • DB transaccional con carga pesada: si tu Postgres ya está al 70% de CPU sirviendo OLTP, agregarle queries vectoriales lo va a saturar. Mueve a una réplica o a una DB dedicada.
  • Requieres filtros geoespaciales avanzados sobre vectores con índices compuestos exóticos: Weaviate maneja esto mejor.
  • Necesitas multi-tenancy estricta con vector store por tenant: posible en pgvector pero engorroso.

Para todo lo demás (chatbots con RAG, semantic search en docs internos, recomendaciones por similitud, knowledge base, hasta unos cuantos millones de chunks), pgvector es la elección por default.

Comparativa técnica y económica para RAG

De acuerdo con la documentación oficial de precios de Pinecone y los tarifarios estándar de Google Cloud Platform y Amazon Web Services, el costo de mantener servicios especializados se dispara cuando se incorporan múltiples ambientes (desarrollo, staging y producción) y lectura intensiva:

Criterio pgvector (Mismo Postgres) Pinecone Serverless Weaviate Cloud
Costo base mensual $0 USD marginales si ya tienes instancia activa Desde ~$70 USD (crece por lecturas y escrituras) Desde ~$25 a $85 USD por sandbox/cluster
Filtros por metadatos SQL completo (JOINs, JSONB, B-Tree, RLS) Filtrado por metadata limitado Índices invertidos propietarios
Latencia de red 0 ms extra (misma VPC / misma máquina) 25-60 ms por llamada externa transfronteriza 20-50 ms según región de despliegue
Consistencia transaccional ACID nativo: si el doc se borra, el vector se borra Eventual (riesgo de registros huérfanos) Eventual (sincronización manual)
Límite recomendado de escala Hasta 5-10 millones de vectores con HNSW Cientos de millones de vectores Decenas de millones de vectores

Setup mínimo en producción

-- Postgres 16+, pgvector 0.7+
CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE doc_chunks (
  id BIGSERIAL PRIMARY KEY,
  doc_id UUID NOT NULL,
  org_id UUID NOT NULL,
  content TEXT NOT NULL,
  embedding vector(1536) NOT NULL,  -- text-embedding-3-small
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- HNSW para producción, NO ivfflat
CREATE INDEX doc_chunks_embedding_hnsw
  ON doc_chunks
  USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);

CREATE INDEX ON doc_chunks (org_id);
CREATE INDEX ON doc_chunks (doc_id);

HNSW vs IVFFlat: usa HNSW

La doc oficial de pgvector lista los dos. En 2026, IVFFlat solo tiene sentido si tienes restricciones de memoria muy duras o si tu workload es exclusivamente offline. HNSW da mejor recall y latencia más estable a cambio de más RAM. Parámetros que funcionan en producción:

  • m = 16: conexiones por nodo. Más alto = mejor recall, más RAM.
  • ef_construction = 64: calidad del índice al construir. 64 es buen balance.
  • SET hnsw.ef_search = 40 por sesión: cuánto explorar al consultar. Súbelo a 80 si necesitas más recall, baja a 20 si quieres velocidad.

Con 100K chunks de 1536 dimensiones en e2-standard-4, latencia p50 de búsqueda es ~15ms. p99 sub-50ms. Suficiente para chatbot en vivo.

Query híbrida: el caso real

Pocas búsquedas son "similitud pura". Lo común es similitud + filtros de negocio (organización, tipo de doc, fecha, permisos). En pgvector se hace en un solo SELECT:

SELECT
  id,
  content,
  doc_id,
  1 - (embedding <=> $1) AS similarity
FROM doc_chunks
WHERE org_id = $2
  AND created_at > NOW() - INTERVAL '180 days'
  AND doc_id = ANY($3)  -- docs a los que el user tiene acceso
ORDER BY embedding <=> $1
LIMIT 8;

El operador <=> es distancia coseno. 1 - distancia da similitud entre 0 y 1. El planner de Postgres combina el índice HNSW con los filtros B-tree de manera competente; no necesitas hacer subqueries manuales.

Afinación de memoria para evitar caídas por OOM

El índice HNSW reside preferentemente en la memoria RAM para evitar accesos aleatorios al disco NVMe que degradarían la latencia. Si tu base de datos experimenta picos de escritura y consultas vectoriales simultáneas, debes ajustar la configuración de Postgres específicamente para este escenario:

  • maintenance_work_mem: Para construir índices HNSW sin abortar por memoria insuficiente, asígnalo temporalmente a 2GB o 4GB durante la ejecución de CREATE INDEX.
  • shared_buffers: Mantén esta directiva en un 25% de la RAM total de tu máquina para permitir que el kernel de Linux use el resto como Page Cache.
  • work_mem: Modéralo en entornos concurrentes (32MB a 64MB por conexión) para prevenir eventos Out Of Memory (OOM Killer) causados por múltiples búsquedas concurrentes.

Patrón de chunking que importa

  • Chunks demasiado grandes (>1500 tokens): el embedding se "promedia" semánticamente y pierdes precisión.
  • Chunks demasiado chicos (<100 tokens): pierdes contexto. Una frase aislada matchea cualquier cosa.
  • Sin overlap: la información que cruza el límite de chunk se pierde. Usa 10-15% de overlap.
  • No guardar el contexto del documento: el chunk debe traer título/sección como prefijo para que el LLM lo entienda al consumirlo.

Punto dulce: 500-800 tokens por chunk, 80 de overlap, prefijo con título del documento.

Lo que sigue rompiendo

  • VACUUM y REINDEX: HNSW se degrada con muchos updates. Programa REINDEX trimestral en horario bajo.
  • Costo de embeddings, no de pgvector: lo caro es generar embeddings, no almacenarlos. Cachea agresivamente y solo regenera si el contenido cambió.
  • Backups: los embeddings son grandes. Tu pg_dump va a crecer. Considera dump separado para tablas vectoriales.

Si tu RAG ya está en Pinecone, mídelo: ¿qué pasaría si migraras a pgvector mañana? La respuesta para la mayoría de proyectos sub-5M de vectores es "ahorras varios miles al año y simplificas el stack". ¿Cuál es tu volumen real de embeddings?

pgvector
rag
postgres
ai-native-saas
← Volver a SCRAM AI Lab