Postgres es una base de datos magnifica hasta que dejas de caber en un solo nodo. En ese momento se abren tres caminos: mover todo a una base distribuida como CockroachDB o YugabyteDB, montar una arquitectura de fragmentos manuales con herramientas externas, o usar Citus. Los tres son validos segun el contexto, pero los tres implican decisiones muy distintas. Este post se centra en Citus porque en 2025 ha terminado de encontrar su sitio: ya no es una apuesta arriesgada ni una promesa comercial, es una extension de Postgres solida que resuelve un problema concreto con menos disrupcion que las alternativas. Despues de acompanar a varios equipos en migraciones hacia y desde Citus, creo que merece una valoracion honesta.
La historia corta: de fork comercial a extension abierta
Citus nacio en 2011 como una startup que ofrecia un Postgres distribuido. Durante anos funciono como una mezcla de codigo abierto y edicion comercial con funciones avanzadas solo en la version empresarial. Microsoft compro la empresa en 2019 y durante dos anos el proyecto se enfrio visiblemente: la comunidad temia que terminara como un producto cerrado de Azure. El giro llego en 2022, cuando Microsoft abrio la totalidad del codigo, incluidas las funciones empresariales historicas, bajo licencia AGPLv3. Desde entonces, las versiones anuales han sido regulares, la actividad en el repositorio es sana y la edicion comercial ha desaparecido.
Esto es relevante porque Citus ya no es un producto con telemetria dudosa y bloqueo de funciones. Es una extension de Postgres que puedes instalar con apt, compilar desde fuentes o desplegar en cualquier distribucion sin pagar licencias. La version actual 13.x es compatible con Postgres 17, lo que significa que puedes combinar las mejoras recientes del motor base con el particionado distribuido sin renuncias. En el mundo de las bases de datos, esta combinacion de codigo abierto real y compatibilidad con la evolucion del proyecto superior es rara y conviene aprovecharla.
Como funciona el modelo de Citus
La idea central de Citus es disenada con Postgres en mente desde el primer dia. En lugar de reescribir el motor de almacenamiento, anade una extension al coordinador y a los nodos trabajadores que intercepta la planificacion de consultas y las distribuye. Desde fuera el cluster se parece a un unico Postgres; te conectas al coordinador por el puerto habitual y lanzas SQL estandar. Por dentro, el coordinador guarda metadatos sobre como estan particionadas las tablas y reparte el trabajo entre los trabajadores.
Citus distingue tres tipos de tabla. Las tablas distribuidas se particionan por una columna llamada clave de distribucion, que define en que trabajador vive cada fila. Las tablas de referencia se replican en todos los nodos porque son pequenas y se consultan cruzadas con las distribuidas. Las tablas locales permanecen solo en el coordinador para datos que no necesitan escalar. Este modelo obliga a pensar la arquitectura desde el diseno: elegir la clave de distribucion correcta es la decision mas importante que tomaras, porque condiciona el rendimiento de todas las consultas posteriores.
La clave de distribucion ideal cumple dos condiciones. Primero, reparte datos de forma razonablemente uniforme entre trabajadores para evitar puntos calientes. Segundo, es la columna que aparece en la mayoria de filtros y uniones, porque eso permite al coordinador dirigir la consulta a un unico trabajador en lugar de dispersarla por todo el cluster. Los casos de exito mas claros que he visto son aplicaciones multi-inquilino donde el identificador de cliente es la clave natural: cada inquilino vive en un trabajador, las consultas del panel de un cliente solo tocan un nodo, y el cluster entero sirve a muchos inquilinos en paralelo.
Donde encaja bien y donde duele
Citus brilla en tres escenarios concretos. El primero es multi-inquilino, donde los datos particionan limpiamente por cliente u organizacion. Aqui la eficiencia es casi lineal: el cluster crece anadiendo trabajadores y la latencia por consulta apenas cambia. El segundo es analitica en tiempo real sobre datos tipo series temporales, donde Citus reparte las consultas agregadas en paralelo entre trabajadores y las consolida en el coordinador. En estas cargas he visto factores de mejora de diez a veinte veces frente a un Postgres monolitico con el mismo hardware total.
El tercer escenario es menos obvio: aplicaciones que han crecido dentro de Postgres hasta llegar a un nodo grande y necesitan el siguiente salto sin reescribir. Migrar a CockroachDB o Spanner implica cambios significativos en el modelo de datos, el SQL, las transacciones y la operacion. Migrar a Citus es mucho mas incremental: sigues con Postgres, las extensiones que usas siguen funcionando en muchos casos, y la aplicacion ve SQL estandar. Esta ruta de menor resistencia tiene valor en equipos donde el coste de un cambio de motor no esta justificado por la urgencia.
Donde duele es igualmente importante. Las consultas que cruzan claves de distribucion diferentes, o que requieren uniones sin la clave, son lentas porque el coordinador tiene que mover datos entre trabajadores. Si tu carga tiene muchas consultas ad-hoc que no respetan el modelo de distribucion, Citus da peor rendimiento que un Postgres monolitico bien tuneado. El segundo punto doloroso es el soporte de transacciones multi-particion: existe, pero es mas lento y fragil que las transacciones locales en un solo Postgres. Los proyectos donde vi a Citus fracasar son precisamente aquellos donde nadie acepto esta limitacion y se intentaron cargas OLTP complejas con transacciones atomicas entre inquilinos.
El tercer punto es la operacion. Un cluster Citus es mas complejo que un Postgres unico: tiene un coordinador que es punto unico de fallo salvo que montes alta disponibilidad con Patroni o similar, tiene trabajadores que fallan de forma independiente, y anadir nodos requiere rebalancear fragmentos, operacion que ha mejorado mucho pero sigue siendo no trivial. Equipos pequenos sin experiencia operativa en Postgres distribuido acaban pasando mas tiempo manteniendo el cluster que desarrollando aplicacion.
Citus frente a las alternativas distribuidas
La pregunta recurrente es como se compara con CockroachDB o YugabyteDB. La respuesta corta es que Citus gana cuando tu carga particiona limpiamente y quieres seguir en Postgres; las otras ganan cuando necesitas transacciones distribuidas sin friccion sobre cualquier acceso o cuando el requisito regulatorio exige un modelo de consenso explicito.
CockroachDB y YugabyteDB son bases distribuidas por diseno desde el primer dia. Implementan consenso Raft en cada rango de datos, ofrecen transacciones ACID globales sin limitaciones topologicas, y se comportan bien con cargas donde cualquier fila puede tocar cualquier nodo. A cambio, la latencia minima de una transaccion es mayor que en Postgres, el SQL compatible cubre el 95 por ciento pero no todo, y el ecosistema de extensiones es mas pobre. Son la respuesta correcta para sistemas donde la distribucion es intrinseca, no un apano evolutivo.
Citus, en cambio, es un atajo inteligente. Acepta que la mayoria de aplicaciones con problemas de escala tienen un particionado natural claro, y si lo respetas, te permite escalar horizontalmente sin salir de Postgres. Para los casos que no tienen ese particionado, Citus no es la respuesta.
Cuando compensa
Mi lectura tras ver migraciones es que Citus compensa cuando se dan tres senales a la vez. Tu aplicacion ya corre en Postgres, ha crecido hasta necesitar mas de un servidor, y tiene un particionado natural claro por cliente, region, proyecto o similar. Si las tres senales estan presentes, Citus ofrece el camino de menor disrupcion y un rendimiento excelente en su rango. Si falta la tercera, estar perdiendo el tiempo: elegiras mal la clave de distribucion y Citus dara resultados peores que un nodo monolitico mas grande.
La segunda lectura es que Citus funciona mejor cuando se adopta como decision arquitectonica temprana, no como parche tardio. Los proyectos que planificaron el modelo de datos con Citus en mente desde el principio escalaron suavemente. Los que llegaron con un Postgres denso tras anos de evolucion organica tuvieron que reestructurar esquemas, mover datos y reescribir consultas antes de ver beneficios. Si el sistema ya tiene problemas de rendimiento hoy, mejor estabilizar el nodo unico primero con replicacion para lectura y caches, y plantear Citus como proxima fase, no como soluciones simultanea al incendio.