De Pinecone a pgvector: una reducción de costes del 97%
Cómo recortamos 97% los costes de base de datos vectorial migrando de Pinecone a pgvector. Una guía técnica detallada sobre la migración.
Cómo recortamos 97% los costes de base de datos vectorial migrando de Pinecone a pgvector. Una guía técnica detallada sobre la migración.
Cuando empezamos Chatsy, elegimos Pinecone para almacenamiento vectorial. Era la elección obvia: creado específicamente para búsqueda vectorial, gran experiencia de desarrollador y rendimiento excelente. El servicio gestionado nos permitía enfocarnos en construir el producto en lugar de gestionar infraestructura.
Resumen rápido:
- Migrar de Pinecone a pgvector recortó nuestros costes de base de datos vectorial en 97%, de $3,000/mes a $90/mes.
- La latencia de consulta mejoró (P95 bajó de 120 ms a 85 ms) porque colocar vectores y metadata juntos elimina idas y vueltas de red.
- La migración tomó 3 semanas en cuatro fases: diseño de esquema, backfill, validación con escritura dual y cutover.
- Para la mayoría de aplicaciones que ya usan PostgreSQL, pgvector es la opción pragmática: obtienes transacciones ACID, backups unificados y herramientas familiares sin infraestructura extra.
Pero a medida que escalamos, nuestra factura de Pinecone creció de $100/mes a más de $3,000/mes. Con cientos de chatbots y millones de chunks de documentos, la trayectoria de coste era insostenible. Sabíamos que tenía que haber una forma mejor.
Esta es la historia de cómo migramos a pgvector, redujimos nuestros costes en 97% y de hecho mejoramos el rendimiento en el proceso.
Esta guía sintetiza detalles operativos de tres categorías de fuentes:
Evitamos afirmaciones puramente de marketing y priorizamos ejemplos que se despliegan en bases de código reales. Cuando citamos cifras de latencia o precisión, la metodología, dataset o condiciones de prueba se indican junto a ellas. Revisado por última vez: abril de 2026.
Antes de entrar en detalles técnicos, establezcamos por qué decidimos migrar. No fue una decisión que tomamos a la ligera: Pinecone funcionaba bien técnicamente. Los problemas eran principalmente económicos y arquitectónicos.
Nuestro uso de Pinecone seguía un patrón predecible: cada cliente nuevo significaba más vectores, y más vectores significaban facturas más altas. El modelo de precios, basado en cantidad de vectores y volumen de consultas, creaba una relación lineal entre crecimiento y coste.
| Mes | Vectores | Coste mensual |
|---|---|---|
| Ene | 500K | $100 |
| Mar | 1.2M | $450 |
| Jun | 3.5M | $1,200 |
| Sep | 8M | $3,000 |
Con esta trayectoria, mirábamos facturas mensuales de más de $10,000 en un año. Para una startup, eso es una tasa de consumo significativa para un solo componente de infraestructura.
Más allá del coste, enfrentábamos un reto arquitectónico: sincronización de datos. Nuestra metadata de documentos vivía en PostgreSQL, pero los embeddings vivían en Pinecone. Cada consulta requería:
Este patrón de doble base de datos creaba retos de sincronización, aumentaba la latencia y complicaba nuestra base de código. Cuando se eliminaban documentos, teníamos que recordar eliminarlos de ambos sistemas. Al reindexar, teníamos que coordinar entre servicios.
Evaluamos cuatro alternativas principales a Pinecone:
Weaviate: excelente base de datos vectorial con vectorización integrada. Sin embargo, ejecutarla nosotros añadía complejidad operativa, y la oferta gestionada tenía preocupaciones de coste parecidas.
Milvus: potente y escalable, pero diseñado para despliegues mucho más grandes de lo que necesitábamos. La sobrecarga operativa no encajaba con el tamaño de nuestro equipo.
Qdrant: moderno y con buen rendimiento, pero relativamente nuevo. Nos preocupaba la estabilidad a largo plazo y la madurez del ecosistema.
pgvector: extensión de PostgreSQL para búsqueda por similitud vectorial. Añade capacidades vectoriales a nuestra base de datos existente.
Elegimos pgvector por varias razones convincentes.
La ventaja más importante fue eliminar el problema de doble base de datos. Con pgvector, nuestros vectores viven junto a nuestros datos relacionales en la misma base de datos, las mismas transacciones, los mismos backups.
sqlSELECT content, embedding <=> query_embedding AS distance FROM documents WHERE chatbot_id = $1 AND organization_id = $2 AND deleted_at IS NULL ORDER BY distance LIMIT 10;
Esta única consulta combina búsqueda por similitud vectorial con filtrado relacional, algo que antes requería múltiples idas y vueltas. La simplificación fue enorme.
PostgreSQL tiene más de 30 años de fiabilidad probada en batalla. Al construir sobre PostgreSQL, heredamos:
No tuvimos que aprender una base de datos nueva, configurar monitoring nuevo ni mantener procedimientos de backup separados.
Nuestra nueva infraestructura cuesta $90/mes en una instancia PostgreSQL gestionada (usamos Supabase). Eso es una reducción del 97% frente a nuestra factura de Pinecone.
La matemática es directa: las instancias PostgreSQL gestionadas son infraestructura commodity con precios maduros y competitivos. Las bases de datos vectoriales son herramientas especializadas con precios especializados.
Migrar datos de producción entre bases de datos requiere planificación cuidadosa. Dividimos la migración en cuatro fases durante tres semanas.
Añadimos una columna vectorial a nuestra tabla existente de documentos:
sql-- Añadir la columna vectorial ALTER TABLE documents ADD COLUMN embedding vector(1536); -- Crear un índice para búsqueda por similitud CREATE INDEX documents_embedding_idx ON documents USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
Elegimos indexación ivfflat sobre hnsw porque:
El parámetro lists = 100 determina el número de clusters. Usamos la regla práctica de sqrt(num_vectors) y planeamos ajustar a medida que crecíamos.
Escribimos un script de migración para copiar todos los vectores existentes de Pinecone a PostgreSQL:
typescriptasync function backfillVectors() { const batchSize = 1000; let cursor = null; do { // Traer un lote de vectores desde Pinecone const response = await pinecone.list({ limit: batchSize, cursor }); const ids = response.vectors.map(v => v.id); const vectors = await pinecone.fetch({ ids }); // Insertar en lote en PostgreSQL const updates = Object.entries(vectors).map(([id, vector]) => ({ where: { id }, data: { embedding: vector.values } })); await prisma.$transaction( updates.map(u => prisma.document.update(u)) ); cursor = response.nextCursor; console.log(`Migrated ${ids.length} vectors`); } while (cursor); }
El backfill corrió durante un fin de semana, procesando aproximadamente 500,000 vectores por hora. Monitoreamos errores y reejecutamos lotes fallidos.
Durante el periodo de transición, escribimos en ambas bases de datos simultáneamente. Esto aseguró que pgvector permaneciera sincronizado mientras validábamos resultados:
typescriptasync function indexDocument(doc: Document, embedding: number[]) { // Escribir en ambos sistemas en paralelo await Promise.all([ pinecone.upsert([{ id: doc.id, values: embedding, metadata: { chatbotId: doc.chatbotId } }]), prisma.document.update({ where: { id: doc.id }, data: { embedding } }) ]); }
También construimos un sistema de validación que ejecutaba consultas contra ambas bases de datos y comparaba resultados. Esto detectó varios casos límite antes de que se convirtieran en problemas de producción.
Después de validar que los resultados de pgvector coincidían con los de Pinecone con 99.9% de precisión, cambiamos las lecturas a pgvector:
typescript// Antes: consulta Pinecone const results = await pinecone.query({ vector: queryEmbedding, topK: 10, filter: { chatbotId } }); // Después: consulta pgvector const results = await prisma.$queryRaw<DocumentResult[]>` SELECT id, content, metadata, embedding <=> ${queryEmbedding}::vector AS distance FROM documents WHERE chatbot_id = ${chatbotId} AND embedding IS NOT NULL ORDER BY distance LIMIT 10 `;
Mantuvimos Pinecone en modo solo lectura durante dos semanas como fallback, y luego lo retiramos por completo.
Las mejoras de rendimiento nos sorprendieron. Esperábamos que pgvector fuera un poco más lento: un tradeoff razonable por el ahorro de costes. En cambio:
| Métrica | Pinecone | pgvector | Cambio |
|---|---|---|---|
| Latencia P50 | 45 ms | 38 ms | -16% |
| Latencia P95 | 120 ms | 85 ms | -29% |
| Latencia P99 | 250 ms | 150 ms | -40% |
| Coste mensual | $3,000 | $90 | -97% |
Sí, pgvector es de hecho más rápido para nuestro caso de uso. La razón principal: colocar vectores y metadata juntos elimina idas y vueltas de red. Cuando ambos tipos de datos viven en la misma base de datos, no hay latencia de red entre la búsqueda por similitud y la obtención de metadata.
Después de ejecutar pgvector en producción durante seis meses, estos son nuestros aprendizajes clave:
Como comentamos en crear para escala, la indexación IVFFlat es más simple, usa menos memoria y funciona excelentemente hasta ~10M vectores. HNSW ofrece mejor precisión a gran escala, pero requiere mucha más memoria. No optimices prematuramente.
El parámetro lists en IVFFlat determina el número de clusters. Muy pocas listas implican consultas lentas (escanean demasiados vectores). Demasiadas listas implican inserts lentos (actualizan demasiados clusters). Usamos sqrt(num_vectors) como punto de partida y ajustamos según monitoring.
Si filtras por tenant (cosa que siempre hacemos), crea índices parciales:
sqlCREATE INDEX documents_embedding_org1_idx ON documents USING ivfflat (embedding vector_cosine_ops) WHERE organization_id = 'org_123';
Esto mejora drásticamente el rendimiento de consulta para tenants grandes.
Las columnas vectoriales son grandes (1536 dimensiones x 4 bytes = 6 KB por fila). Las tuplas muertas se acumulan más rápido que con datos típicos. Ejecutamos vacuum agresivo para prevenir bloat.
Los índices IVFFlat necesitan reconstruirse cuando la distribución de datos cambia de forma significativa. Reconstruimos índices trimestralmente, programado durante periodos de bajo tráfico.
La migración tomó 3 semanas de ingeniería y nos ahorró $35,000/año. Más importante aún, simplificó nuestra arquitectura, redujo complejidad operativa y de hecho mejoró el rendimiento.
No toda carga de trabajo es apta para pgvector. Si necesitas vectores a escala de miles de millones con latencia sub-10 ms, las bases de datos vectoriales dedicadas siguen teniendo sentido. Pero para la mayoría de aplicaciones, especialmente las que ya usan PostgreSQL, pgvector es la opción pragmática, particularmente cuando se combina con búsqueda híbrida para calidad de recuperación óptima.
Para más sobre cómo construimos la infraestructura de Chatsy, revisa nuestros posts sobre búsqueda híbrida y crear para escala.
Los agentes de IA de Chatsy usan esta misma arquitectura pgvector para entregar recuperación rápida y precisa sobre tu base de conocimiento, sin base de datos vectorial externa. Si estás creando automatización de soporte sobre PostgreSQL, ya estás a medio camino.
Los costes de Pinecone escalan linealmente con cantidad de vectores y volumen de consultas; nuestra factura creció de $100 a $3,000/mes. pgvector elimina eso usando tu instancia PostgreSQL existente. También eliminas el problema de doble base de datos: vectores y metadata viven juntos, así que no hay lógica de sincronización, ni idas y vueltas extra, y la arquitectura es más simple.
Sí. Chatsy migró a pgvector y lo ha ejecutado en producción durante seis meses. PostgreSQL ofrece transacciones ACID, recuperación point-in-time, replicación y herramientas maduras. Para la mayoría de aplicaciones bajo ~10M vectores, pgvector con indexación IVFFlat es estable y tiene buen rendimiento. Usa HNSW para mayor escala si hace falta.
En nuestra migración, pgvector fue más rápido: la latencia P95 bajó de 120 ms a 85 ms. Colocar vectores y metadata juntos elimina idas y vueltas de red entre la base de datos vectorial y PostgreSQL. P50 mejoró 16% y P99 mejoró 40%, mientras el coste mensual bajó 97% ($3,000 a $90).
El proceso tiene cuatro fases: (1) añadir una columna vectorial e índice IVFFlat a PostgreSQL, (2) hacer backfill de vectores desde Pinecone en lotes, (3) escribir en ambos sistemas y validar resultados, (4) cambiar lecturas a pgvector y retirar Pinecone. Planifica unas 3 semanas de tiempo de ingeniería.
Recortamos costes de base de datos vectorial en 97%, de $3,000/mes a $90/mes en una instancia PostgreSQL gestionada. Eso equivale a aproximadamente $35,000/año de ahorro. PostgreSQL gestionado es infraestructura commodity con precios competitivos; las bases de datos vectoriales dedicadas tienen un premium que puede no justificarse para cargas típicas.
Ve más allá del RAG básico con estrategias de chunking listas para producción, re-ranking con cross-encoders, transformaciones de consulta y pipelines de recuperación híbrida, con ejemplos de código y métricas de evaluación.