El vídeo abre con una provocación: Instagram sirve a 2.000 millones de usuarios en Postgres, mientras que Reddit, Notion, Discord y Strava también mantienen gran parte de su carga en Postgres. Todos evaluaron las alternativas, todos se quedaron. La pregunta surge de forma natural: ¿qué saben estos equipos que se pierde el mantra de «Postgres no escala»?
La historia empieza en 2010: tres ingenieros, máquinas virtuales alquiladas, un almacén de objetos para las fotos y un único Postgres para todo lo demás (cuentas, metadatos, comentarios, likes, el grafo de seguidores). Con 10 millones de usuarios en 2011, el panorama no cambia. En la adquisición de mil millones de dólares en 2012 hay 27 millones de usuarios en una sola base de datos de 2 terabytes. La lección que el vídeo guarda para el final germina aquí: una tecnología aburrida bien gestionada vence a una tecnología nueva mal gestionada.
En 2012, la máquina única alcanza su techo: el servidor más grande alquilable de la época se queda sin memoria, el rendimiento del disco está saturado, no queda ningún sitio para escalar verticalmente. El reflejo que el vídeo recomienda importa: en lugar de cambiar de base de datos en pánico, encontrar exactamente qué está obstruido y arreglarlo. Y la primera obstrucción resulta ser distinta de lo que la mayoría adivina.
El primer muro no es el tamaño de los datos, son las conexiones. Cada conexión ocupa unos 1,3 megabytes; cuando decenas de servidores de aplicación abren cada uno su propio pequeño pool (el ejemplo detallado es 50 servidores por 30 conexiones) se obtienen 1500 conexiones consumiendo 2 gigabytes antes de que se ejecute una sola consulta útil. La solución es PgBouncer: un proxy ligero entre la aplicación y la base de datos que multiplexa miles de conexiones entrantes sobre unas pocas decenas de conexiones reales. La memoria vuelve a la caché de páginas, al ordenamiento y a la planificación de consultas. La afirmación es tajante: para cualquier configuración seria de Postgres sin un pooler, esta es la corrección de mayor impacto de la semana.
El pooling compra un respiro, pero la carga sigue creciendo y llega el coro habitual: «hora de pasar a NoSQL». El vídeo rechaza la receta, argumentando que el dolor del particionado no desaparece en Cassandra, solo se esconde detrás de otra abstracción. Y no hay billete de vuelta: una vez que cambias, volver es casi imposible. Instagram decide en cambio hacer que el propio Postgres sea horizontal.
La decisión de sharding está tomada, pero la clave de sharding sella su destino. El candidato natural es el id de usuario: las fotos y los likes de un usuario viven en un solo shard, «mostrar mi perfil» golpea un único shard, rápido y limpio. Pero la consulta definitoria de una red social es «mostrar fotos de las personas que sigo», y cuando 200 seguidos se dispersan por 50 shards se convierte en una pesadilla: fanout a 50 bases de datos, fusión y ordenación en la capa de aplicación, un feed tan lento como el shard más lento, modos de fallo completamente nuevos. El compromiso es permanente; el equipo apuesta a que puede resolver las consultas entre usuarios en la capa de aplicación con caché, fanout inteligente y feeds precalculados.
Llega la idea que el vídeo llama «la arquitectura en sí»: separar cómo se particionan los datos de dónde viven físicamente. El equipo define unos pocos miles de shards lógicos (esquemas de Postgres con tablas idénticas), todos alojados al principio en una sola máquina física. La aplicación solo pregunta «qué shard lógico posee este usuario». Cuando una máquina se llena, no se reescriben datos; los shards lógicos se copian a una nueva caja con replicación en streaming integrada y se actualiza la tabla de mapeo (en el ejemplo, la mitad del rango de shards de un nodo casi lleno se mueve al nuevo nodo y ambos se estabilizan a media capacidad). Con el número de shards nunca codificado en el código, el crecimiento se convierte en un cambio de configuración.
Los contadores clásicos de autoincremento chocan de inmediato en esta disposición: si cada shard acuña su propia serie 1-2-3, dos fotos distintas comparten un mismo id. Los ids aleatorios de 128 bits son enormes y desordenados, lo que hace costosas las consultas temporales; un servidor central de tickets es un punto único de fallo; un servicio Snowflake externo es una cosa más que monitorizar. La respuesta de Instagram es un número de 64 bits en tres partes: una marca de tiempo en milisegundos de 41 bits desde una época personalizada (41 años de margen), un id de shard de 13 bits (hasta 8 mil shards), una secuencia por milisegundo de 10 bits (cientos de miles de ids por segundo por shard). Se ejecuta como una pequeña función de Postgres en cada shard, sin coordinación ni dependencias externas; con la marca de tiempo en los bits altos, ordenar por id significa del más nuevo al más antiguo, sin necesidad de un índice temporal aparte. El patrón luego se extendió por la industria hasta Discord y Slack; la advertencia práctica es adoptarlo desde el primer día, no después de mil millones de filas.
El vídeo también destaca tres funcionalidades infrautilizadas que ya están dentro de Postgres. Índices parciales: indexar solo los últimos 30 días de una tabla de mil millones de filas reduce el índice diez veces y lo mantiene pequeño a medida que los datos antiguos caducan. Índices funcionales: indexar los primeros 8 caracteres de un token de 64 caracteres en lugar de la cadena completa mantiene las búsquedas rápidas con una décima parte del tamaño. Replicación lógica: transmitir en tiempo real cada inserción, actualización y borrado al índice de búsqueda, la invalidación de caché y el almacén de analítica, en lugar de construir a mano escrituras dobles y colas en la aplicación.
Una nota de honestidad: esta es la historia de 2010-2015; tras la adquisición, el grafo de seguidores de Instagram se trasladó a la infraestructura de Meta y hoy vive en TAO, un sistema de grafos distribuido. Pero las cinco reglas del vídeo siguen vigentes: no hacer sharding hasta que sea forzoso (el equipo esperó hasta 27 millones de usuarios), separar lo lógico de lo físico, adoptar ids estilo Snowflake desde el primer día, arreglar primero el pooling de conexiones, y comprar infraestructura nueva solo para problemas genuinamente nuevos (búsqueda vectorial, series temporales, grafos). La tesis final: el cuello de botella nunca es la base de datos, es la arquitectura que la rodea.
Comentario de la IA
""Mi conclusión es contundente: los problemas de escalado casi nunca son culpa de la base de datos, sino de la arquitectura que la rodea; hacer funcionar bien una tecnología aburrida suele costar menos que migrar a algo emocionante.""
Fuentes
6 enlaces; ninguna otra noticia publicada los cita. Stories sharing a link do not confirm each other; a source's origin is not inferred from how often it is cited.
- @youtube https://www.youtube.com/watch?v=YLoYcwnqVzM
- @instagram-engineering https://instagram-engineering.com/sharding-ids-at-instagram-1cf5a71e5a5c
- @instagram-engineering https://instagram-engineering.com/handling-growth-with-postgres-5-tips-from-instagram-d5d7e7ffdfcb
- @instagram-engineering https://instagram-engineering.com/what-powers-instagram-hundreds-of-instances-dozens-of-technologies-adf2e22da2ad
- @planetscale https://planetscale.com/blog/the-history-of-postgres-sharding
- @guidgenerator https://guidgenerator.com/engineering-blog/how-big-tech-generates-unique-ids-at-scale-twitter-snowflake-instagram
postgres · sharding · pgbouncer · id snowflake · instagram