35 puntos por GN⁺ 2025-05-24 | 2 comentarios | Compartir por WhatsApp
  • OpenAI compartió en PGConf.dev 2025 cómo usa PostgreSQL sin sharding y aun así maneja de forma eficiente el tráfico de cientos de millones de usuarios
  • Para resolver el problema del cuello de botella en escritura, adoptó distintos enfoques como distribución de escrituras, optimización de consultas y gestión del esquema
  • Señaló como temas principales los límites estructurales y las dificultades operativas de PostgreSQL, como la inflación de tablas/índices por el diseño de MVCC y la latencia de replicación causada por WAL
  • Las estrategias de optimización de consultas, como distribuir la carga de lectura, limitar transacciones largas y minimizar el uso de ORM, fueron clave
  • OpenAI alcanza 1 millón de QPS con más de 40 réplicas distribuidas geográficamente, y garantiza alta disponibilidad incluso cuando ocurren fallas

Caso de escalado masivo de PostgreSQL en OpenAI

Antecedentes

  • Muchos de los servicios principales de OpenAI dependen de PostgreSQL
  • Si ocurre una falla en la base de datos, el impacto afecta directamente a todo el servicio
  • En el pasado, servicios importantes como ChatGPT sufrieron interrupciones debido a problemas con PostgreSQL
  • OpenAI opera una arquitectura Primary-Replica (un solo Primary + más de 40 Replicas) sobre una base de datos administrada de Azure
  • En un entorno que atiende a 500 millones de usuarios activos mensuales, la escalabilidad es un factor clave para el éxito del negocio

Principales desafíos

  • El tráfico de lectura puede distribuirse entre múltiples Replicas, pero las solicitudes de escritura se concentran en un solo Primary, lo que genera un cuello de botella
  • Puntos principales de mejora
    • Descargar y distribuir todas las escrituras posibles
    • Minimizar nuevas conexiones directas de servicios nuevos al DB Primary
  • Por la estructura de MVCC (control de concurrencia multiversión), existen desventajas como inflación de tablas/índices, ajuste complejo de recolección de basura y verificaciones de visibilidad de índices
  • A medida que aumenta la cantidad de Replicas, también crece con fuerza el tráfico de WAL (Write-Ahead Logging), y el ancho de banda de red se convierte en otro cuello de botella

Medidas de respuesta

Distribución de carga del DB Primary

  • Predicción y mitigación de la carga de escritura:
    • Descargar todas las escrituras posibles
    • Evitar escrituras innecesarias a nivel de aplicación
    • Aplicar Lazy Write y ajustar los ciclos de backfill de datos
  • La carga de lectura se distribuye a las Replicas tanto como sea posible; cuando inevitablemente debe procesarse en el Primary, se exige alta eficiencia

Optimización de consultas

  • Las transacciones de larga duración ocupan recursos del sistema por mucho tiempo y retrasan la recolección de basura
  • Se aplican Timeouts por sesión/consulta/cliente, y se limitan las sesiones idle in transaction
  • Se indica que el uso de ORM puede aumentar la ineficiencia, por lo que se recomienda usarlo con cuidado
  • Se optimizaron consultas complejas con múltiples joins, por ejemplo joins entre 12 tablas

Respuesta ante punto único de falla (SPOF)

  • Si el Primary falla, no se pueden realizar escrituras; en cambio, las Replicas garantizan continuidad de lectura incluso si algunas presentan fallas
  • Las solicitudes importantes (alta prioridad) se procesan en una Replica dedicada, minimizando la interferencia de solicitudes de baja prioridad

Gestión del esquema

  • La creación de nuevas tablas y la introducción de nuevas cargas de trabajo están restringidas en el clúster
  • Para agregar o eliminar columnas, solo se permiten operaciones ligeras dentro de un límite de 5 segundos; no se permiten operaciones que requieran reescritura completa de la tabla
  • La creación/eliminación de índices solo se permite con la opción CONCURRENTLY
  • Se presentó el problema de que consultas largas de más de 1 segundo bloquean continuamente los cambios de esquema, por lo que se requiere optimizar o descargar esas consultas a nivel de aplicación

Resultados operativos

  • El clúster completo procesa 1 millón de QPS (lecturas + escrituras) y soporta los principales servicios de OpenAI
  • Incluso tras añadir unas 40 Replicas, no aumentó la latencia de replicación
  • Se desplegaron Read-only Replicas en distintas regiones, manteniendo baja latencia
  • En los últimos 9 meses, solo ocurrió 1 incidente SEV0 relacionado con PostgreSQL
  • Se aseguró capacidad suficiente para cubrir el crecimiento futuro

Casos de falla

  • Falla de caché que provocó un efecto cascada
  • Un bug en el que, con alta ocupación de CPU, el proceso WALSender dejaba de enviar WAL y caía en un estado de bucle, lo que provocó latencia de replicación

Solicitudes de mejora funcional propuestas para PostgreSQL

  1. Gestión de índices: se propone una función de Disable para desactivar de forma segura índices innecesarios y así minimizar el riesgo antes de eliminarlos
  2. Observabilidad: se solicita proveer métricas basadas en histogramas/cuantiles de latencia como p95 y p99
  3. Historial de cambios de esquema: se pide una función para guardar cambios de esquema como DDL
  4. Claridad semántica de las vistas de monitoreo: se consulta por las causas y respuestas ante sesiones específicas que permanecen mucho tiempo en estado ClientRead
  5. Optimización de parámetros por defecto: se señala que los valores por defecto de PostgreSQL son demasiado conservadores y se solicita introducir mejores valores por defecto o heurísticas

Comentarios de Lao Feng

  • La estrategia de escalado de OpenAI en un entorno tan extremo es un caso práctico valioso para los desarrolladores del núcleo de PostgreSQL
  • Servicios de gran escala como Tantan en China también han tenido experiencias similares (33 Replicas, 400 mil QPS, adopción de sharding del lado de la aplicación)
  • En el entorno actual de hardware de alto rendimiento, incluso con un solo clúster de PostgreSQL como el de OpenAI puede lograrse una escalabilidad agresiva, lo que sugiere que una base de datos distribuida no siempre es indispensable
  • OpenAI utiliza Azure PostgreSQL administrado, más de 40 Replicas, despliegue cross-region y Kubernetes + PgBouncer
  • Aunque recibe soporte intensivo del equipo de Azure PostgreSQL, siguen siendo esenciales la capacidad operativa del equipo de aplicación/DBA y la observabilidad
  • Se menciona el monitoreo con Datadog, así como la carga en rendimiento y costos
  • El know-how operativo, la experiencia en fallas y los activos de DBA son clave para la calidad del servicio

Preguntas y respuestas de Lao Feng

Función para desactivar índices

  • Internamente en PostgreSQL es posible desactivar índices mediante el campo indisvalid (aunque requiere privilegios de superuser y está restringido en entornos RDS)
  • La alternativa práctica es verificar mediante monitoreo si el índice se usa y luego eliminarlo de forma segura

Ampliación de observabilidad: latencia P95/P99

  • El soporte de métricas por cuantiles en pg_stat_statements es difícil debido al overhead de memoria, pero existen alternativas como monitoreo de latencia con pg_stat_monitor/eBPF/capa de aplicación
  • En entornos de Azure PostgreSQL administrado, algunas opciones (acceso al servidor, eBPF, etc.) no están soportadas

Historial de cambios de esquema

  • Se puede usar archivos de log, pgaudit, CREATE EVENT TRIGGER, pg_ddl_historization, etc. (aunque requiere privilegios de superuser y Azure RDS tiene restricciones de soporte)
  • Lo que se pide es un historial almacenado en una vista/tabla del sistema que pueda consultarse

Significado de las vistas de monitoreo

  • La combinación State=Active + WaitEvent=ClientRead significa que durante la ejecución de un statement se está esperando entrada del cliente, y puede deberse a varias causas, no necesariamente a un bug
  • Es posible minimizar efectos secundarios limitando la duración de las conexiones (por ejemplo, configuración de expiración en la capa de red como HAProxy, o gestión de vida útil del pool de conexiones del cliente), aunque no está claro si Azure soporta esa función

Parámetros por defecto

  • Los valores por defecto de PostgreSQL son demasiado conservadores, pero pueden compensarse con heurísticas específicas por servicio o ajuste automático de parámetros (RDS, Pigsty, etc.)
  • Si en el futuro se incorporara a las herramientas de PostgreSQL una función de detección y aplicación automática según las especificaciones de hardware, se reduciría la carga operativa en campo

Opción de operación propia (self-hosting)

  • En la práctica, muchos de los problemas operativos derivan no tanto de PostgreSQL en sí, sino de las limitaciones del servicio administrado de Azure
  • Si se construye de forma propia un clúster de PostgreSQL sobre SSD NVMe en un entorno IaaS (por ejemplo con Pigsty), aumentan la flexibilidad funcional y operativa
  • Se menciona que, usando soluciones como Pigsty, sería posible resolver de antemano la mayoría de los requisitos de OpenAI, por lo que vale la pena considerarlo según la escala y las necesidades

2 comentarios

 
GN⁺ 2025-05-24
Comentarios en Hacker News
  • Asistí a PGConf la semana pasada y me impresionó que esta charla fuera una de las sesiones con más público, sobre todo porque la mayoría de las sesiones en esa conferencia más bien introspectiva estaban enfocadas en el desarrollo del propio Postgres, así que este caso de uso se sintió fresco. Siempre hay que recordar que muchos equipos no saben a fondo cómo escalar ciertas partes del stack cuando su producto empieza a crecer con éxito, y esta charla fue evaluada como una gran historia sobre cómo un equipo pequeño supera problemas y va aprendiendo en el proceso. Más que reacciones simplificadas como “¿pero no deberían hacerlo así?”, dio vida al proceso de crecimiento y a la enorme popularidad del producto con una historia real de usuarios, por lo que pareció una sesión perfecta para un evento centrado en desarrolladores internos. El mensaje central de la charla fue que, si no tienes muchas escrituras, puedes escalar Postgres a un volumen de lectura enorme solo con nodos de solo lectura (read replicas) y una arquitectura de maestro único. Se argumenta que ese mensaje aplica precisamente a la mayoría de las apps. En la sesión de preguntas y respuestas, la mayoría de las preguntas vinieron de desarrolladores del núcleo de Postgres que querían aprender del caso de uso, con casi nada de intención crítica, y la impresión fue que la comunidad de Postgres es realmente amable y abierta

    • Sobre el mensaje de que “si no hay muchas escrituras, puedes escalar muchísimo el rendimiento de lectura de Postgres con un solo maestro y réplicas de solo lectura”, alguien comenta que, al hacer entrevistas de diseño de sistemas, siente que demasiados candidatos quieren introducir primero arquitecturas distribuidas gigantes o sistemas que terminan rompiendo la consistencia incluso para sistemas simples con algo como 5 lecturas por segundo. Diez millones de usuarios, en realidad, tampoco es una escala tan grande. Ojalá más gente se diera cuenta de que, mientras toda la industria se obsesiona con el escalado horizontal, el hardware real se ha vuelto mucho más rápido y más grande de lo que uno imagina. Vivimos en un mundo donde puedes rentar en Amazon un servidor con 32 TB de RAM. Incluso a gran escala, las garantías ACID siguen siendo demasiado valiosas

    • Gracias por resumir justo el mensaje central que esta charla realmente quería transmitir (Bohan)

    • Preguntan si hay algún lugar donde se puedan ver las diapositivas o la grabación de esta charla

    • Alguien opina que este hilo le pareció un poco duro con ese equipo. Explica que los usuarios de HN con mucha experiencia en esta área tienen interés en cómo se escaló arquitectónicamente un servicio masivo como ChatGPT y en cómo contrata una empresa con recursos casi ilimitados. Interpreta que el mensaje de la charla de “ten cuidado con los ORM porque pueden generar consultas ineficientes fácilmente” es en sí una señal de que ese equipo todavía no tiene tanta experiencia operando infraestructura de este tamaño

  • Desde el punto de vista de la flexibilidad, hacer self-hosting de Postgres resulta atractivo (por cosas como privilegios de superusuario o uso de funciones avanzadas), pero da la impresión de que operarlo directamente sí preocupa. También existe el deseo de que los proveedores cloud soporten de forma estándar una función para desactivar índices en el planificador de consultas antes de eliminarlos de verdad. Si se trata de una empresa grande, parece perfectamente razonable elegir self-hosting para poder personalizar el stack

    • Explican que en Postgres ya existen varias maneras de forzar o desactivar el uso de un índice, y que también se pueden usar en instancias administradas de Postgres en la nube. Por ejemplo, ajustar la configuración del planificador por consulta (como enable_indexscan=off), o meter una operación aritmética simple en la cláusula where para evitar intencionalmente el uso del índice, además de la extensión pg_hintplan (que permite dar pistas en comentarios sobre qué índice usar; referencia: https://pg-hint-plan.readthedocs.io/en/latest/hint_table.html#hints-for-scan-methods)

    • (Aclara que forma parte del equipo de Azure Postgres) OpenAI no usa self-host, sino PostgreSQL administrado por Azure (Flexible Server)

    • El propio ponente de OpenAI (Bohan) aclaró directamente que no están en un entorno self-host, sino usando Azure Database for PostgreSQL. Se disculpa por no haber dejado más claro durante la charla, aunque sí mencionó varias veces “Azure Postgres”, que se trataba de un servicio administrado por Microsoft

    • Alguien comenta que en MySQL o MariaDB existe DDL para marcar índices como INVISIBLE o IGNORED y hacer que el planificador los ignore, y le sorprende que no haya una función parecida en Postgres

    • Solo cita la frase original: “La ventaja de hacer self-hosting de postgres es la flexibilidad…”

  • Ante la petición de una función para registrar el historial de eventos de cambios de esquema (agregar/eliminar columnas, etc.), responden que ya se puede implementar en tiempo real usando EVENT TRIGGER, y que se puede consultar como ejemplo el caso de Aquameta (https://github.com/aquametalabs/aquameta)

    • Explican que ellos también están implementando en su propio entorno Postgres una función de historial de cambios DDL. Postgres en sí es muy potente y permite implementarlo de muchas maneras, pero el historial y los logs operativos de bases de datos grandes o críticas también son necesidades muy comunes. Sostienen que la mayoría no se da cuenta de su importancia hasta vivirlo en carne propia. No solo en cambios DDL: cuando se reflejan políticas operativas importantes (por ejemplo, cambios en el modelo de precios o personalización de SKU/precios), también es indispensable garantizar “auditabilidad”. Si diseñas completamente el modelo relacional, al final en una app real solo algunas tablas cambian con frecuencia y la mayoría son tablas “estáticas” que casi no cambian; cuando esas tablas sí cambian, conviene dejar un historial detallado para facilitar la interpretación de datos pasados o un rollback

    • Nosotros (Xata) usamos tanto pgroll (https://github.com/xataio/pgroll) como pgstream (https://github.com/xataio/pgstream) con EVENT TRIGGER para detectar cambios DDL y registrar historial de migraciones de esquema, o para incluir eventos de cambio de esquema en el flujo de replicación lógica. Eso sí, en la mayoría de los DBaaS basados en Postgres EVENT TRIGGER está parcialmente restringido por los privilegios de superusuario; RDS/Aurora y Xata sí lo soportan, y Supabase se está preparando para soportarlo también

    • Gracias por acordarte de Aquameta, y deja caer que pronto viene una función nueva muy buena

  • Se argumenta que este contenido (creación concurrente de índices a gran escala, evitar reescrituras de tablas, distribución de tráfico, timeouts de transacciones, réplicas de lectura, etc.) en realidad es casi indispensable —y conocimiento básico— incluso para operar a escalas mucho menores que OpenAI. También se dice que las peticiones que hacen a Postgres son cosas que la gente viene pidiendo desde hace mucho tiempo, y que aunque el título lo llame “Next Level”, en realidad se parece más a un esfuerzo desesperado por seguir escalando manteniendo un maestro único [en una situación con limitaciones para nuevas cargas de trabajo]. El punto clave es aguantar sin problemas una gran carga de lecturas, pero eso en sí ya es el manual clásico de réplicas de lectura y escalado horizontal. También advierten que la forma de desactivar índices manipulando el campo interno (indisvalid) es un truco no soportado oficialmente, y que este tipo de ajustes al catálogo del sistema son peligrosos. Incluso la idea de revisar vistas de monitoreo para ver si un índice se usa y luego borrarlo no es una solución perfecta; para tener más confianza sobre qué índice es necesario o innecesario, hay que revisar también los planes de consulta

    • El artículo original dice que OpenAI está procesando un millón de consultas por segundo en Azure, y alguien interpreta que ese nivel sí es bastante impresionante en un entorno cloud real, sobre todo cuando usas almacenamiento basado en red. Aun así, como el total está repartido entre unas 40 réplicas de lectura, eso da alrededor de 25 mil QPS por instancia, así que no resulta tan sorprendente. En cuanto al debate sobre el uso de índices, explica que si entiendes bien las estadísticas actuales y las características de la base de datos, basta con comprobar qué índice conviene usar y si las condiciones/proyecciones de la consulta respetan bien el left-most prefix del índice

    • Señalan que no hubo ninguna explicación de por qué OpenAI no hace sharding de Postgres, y que eso resulta frustrante. Parece que con sharding por usuario ya se resolvería el problema mucho más fácilmente, así que se preguntan por qué insisten en mantener un solo maestro

  • Parece que están usando replicación física, pero alguien comenta que actualmente está considerando migrar a replicación lógica para reducir costos (bajando el tráfico saliente entre regiones). Como la replicación lógica nativa parece haber mejorado bastante desde Postgres 17, quiere saber si en producción ya vale la pena

  • Se señala como raro que, para responder a consultas diversas, seguramente también estén usando otros motores de almacenamiento (clave-valor, búsqueda, búsqueda vectorial, caché, etc.), pero que la charla se enfocó únicamente en Postgres. Se especula que internamente probablemente sí aplican varias estrategias para repartir tráfico y carga de muchas maneras

  • Alguien se pregunta si sería posible obtener mejor rendimiento operando directamente solo la instancia de escritura en un servidor dedicado con SSD local de alta velocidad, mientras que las lecturas se atienden solo en un servicio administrado

  • Fuerte postura de “deberían hacer sharding de la DB”. La opinión es que con solo fragmentar por usuario/organización podrían resolver de forma sencilla los problemas principales que están enfrentando. Hay molestia porque intentar varios rodeos complejos termina siendo dar vueltas innecesarias

    • En la charla, el mensaje central fue que incluso sin hacer sharding, se puede escalar a un rendimiento enorme con una arquitectura de maestro único, y que por supuesto sí evaluaron el sharding, pero los trade-offs no cuadraban y con la arquitectura actual igual pudieron escalar

    • Respuesta directa del ponente de OpenAI (Bohan): su carga de trabajo no es fácil de fragmentar, y las cargas con muchas escrituras ya se separaron de PostgreSQL para manejarse como shards; lo que queda es casi de solo lectura, así que introducir sharding ahora requeriría un esfuerzo enorme. Por ahora consideran que con Azure Database for PostgreSQL todavía tienen suficiente escalabilidad y margen para el futuro. Aun así, no piensan descartar sharding por completo a largo plazo; simplemente no es una prioridad de corto plazo

    • Sostienen que el sharding no es tan simple como parece. La razón de usar una base de datos potente es que permite análisis y consultas complejas; si lo único que buscas es almacenar y distribuir datos, entonces usar varios montajes NFS sería incluso más sencillo

    • Comentan con realismo que no es nada fácil aplicar sharding de forma simple a una base de datos brutal del tamaño de un millón de consultas por segundo. Aunque una organización parezca una clave natural de partición, a esta escala ya no hay nada verdaderamente simple

    • Respuesta de total acuerdo con la idea anterior

  • Sobre el comentario de la charla de que hay que usar los ORM con cuidado, alguien dice que cree que todos los ORM (especialmente los ORM multiplataforma para varias bases de datos) son problemáticos. Sostiene que usar ORM hace que uno piense los patrones de datos solo al nivel del código de aplicación, y al final te impide aprovechar casi por completo las funciones potentes que ofrece cada base de datos. Dice que él no usa ORM en absoluto y aprovecha activamente consultas y funciones específicas de Postgres; centrarse en el poder de la base de datos, más que en el lenguaje o la conveniencia, da mucho más beneficio. La conclusión es que escribir buen SQL a mano trae felicidad a todo el sistema

    • Alguien cuenta que cuando migró de DB2 a psql, el ORM le ayudó mucho a minimizar el downtime. Gracias al ORM, el cambio de base de datos fue transparente y casi no tuvo que tocar la mayor parte de la lógica. Además, no todos los desarrolladores están acostumbrados a escribir consultas directamente, y cuando las consultas se mezclan con el código puede ser muy difícil refactorizar o entenderlo. Al final, explica, SQL también terminará abstraído como una librería

    • Tras usar Django ORM durante mucho tiempo y considerarlo un software realmente sobresaliente, alguien comenta que recientemente, usando sqlc, siente que convertir directamente consultas en código Go es más bien el punto medio ideal entre un ORM y SQL crudo

    • Otra postura: simplemente no has probado un ORM realmente bueno (por ejemplo, Entity Framework Core)

  • Comentario ligero de que el título “Scaling PostgreSQL to the Next Level at OpenAI” parece corresponder mucho mejor al título real de la charla

 
ddogi 2025-05-25

Parece que productos comerciales como Oracle RAC o DB2 pureScale, que permiten múltiples write, ni siquiera se consideran como opciones.