La rejilla completa: qué combinaciones existen y cuáles están vacías
Cruzar autoridad, unidad y alcance produce una rejilla de doce celdas donde unas pocas concentran casi todo lo existente y otras están vacías por razones estructurales, no por falta de tiempo o de talento.
Los tres ejes ya están sobre la mesa: quién tiene derecho a rechazar una escritura, qué objeto viaja y se compara, y qué subconjunto del universo baja al dispositivo. Cruzarlos produce una rejilla de doce celdas, y lo primero que sorprende al dibujarla es que está casi vacía: unas pocas casillas concentran prácticamente todo lo que existe hoy, unas cuantas están habitadas con restricciones llamativas, y varias están desiertas. La reacción cómoda es suponer que las desiertas son oportunidades sin explotar esperando a alguien con tiempo. Esta lección defiende exactamente lo contrario y lo demuestra celda por celda: las combinaciones vacías lo están porque se contradicen a sí mismas, y entender por qué se contradicen enseña más sobre el problema que cualquier recorrido por la documentación de los productos. Al final, la rejilla se revela como algo más simple y más útil de lo que aparenta, y se convierte en el mapa con el que el nivel siguiente puede examinar herramientas concretas sin perderse en sus nombres comerciales.
- Construir la rejilla completa de doce celdas y saber ubicar en ella cualquier sistema, lo declare o no.
- Reconocer las combinaciones realmente pobladas y qué las hace viables.
- Argumentar por qué ciertas celdas están vacías por contradicción interna y no por falta de madurez.
- Disponer de una prueba rápida para evaluar cualquier motor nuevo que se anuncie a partir de mañana.
Cruzar los tres ejes
La rejilla se construye multiplicando: dos posiciones de autoridad, servidor autoritativo o convergencia sin árbitro; dos unidades, fila con esquema o documento con identidad; y tres alcances, total, por consulta o por colección. Doce celdas. Antes de recorrerlas conviene ser honesto sobre la simplificación: los dos primeros ejes son continuos y aquí se han reducido a extremos, así que muchos sistemas reales caen entre dos casillas o incluso ocupan dos a la vez, con un camino de bajada en una y uno de subida en otra. La rejilla no pretende ser una clasificación exhaustiva sino un instrumento para pensar, y su valor está más en las casillas que rechaza que en las que acepta.
Al colocar los sistemas mencionados en las lecciones anteriores aparece un patrón inmediato que no debería tener explicación si los ejes fueran independientes. Lo poblado se agrupa en dos zonas alejadas entre sí: una donde hay servidor autoritativo, filas y alcance calculado, y otra donde no hay árbitro, la unidad es el documento y el alcance se decide por pertenencia. Entre ambas zonas hay muy poco, y no es un vacío uniforme de exploración pendiente: es un vacío con forma. Cuando un espacio de diseño presenta huecos con forma, la explicación casi nunca es histórica; suele ser que dos requisitos de la misma casilla se anulan.
Las celdas pobladas
Autoritativo, filas, por consulta
El servidor acepta o rechaza cada mutación y mantiene vivos los resultados de las consultas declaradas. Es la zona de Zero y del camino de bajada de ElectricSQL.
Autoritativo, filas, por colección
Reglas que reparten los datos en cubos compartidos y SQLite completo en el cliente, con escrituras que pasan por tu servidor. La zona de PowerSync.
Autoritativo en el orden, filas, total
Un registro determinista de mutaciones cuyo servidor arbitra la secuencia y no el contenido, con el estado derivado en SQLite. La zona de LiveStore.
Sin árbitro, documentos, por pertenencia
Sin evaluador, con documentos como unidad de sincronización, de permiso y de conflicto, y acceso resuelto con claves. La zona de Jazz.
Merece la pena mirar despacio por qué cada una de esas cuatro es coherente consigo misma, porque la coherencia es justo lo que faltará en las vacías. La primera funciona porque el servidor que evalúa el predicado de la consulta es el mismo que evalúa la mutación: la infraestructura que hace falta para decir que no a una escritura es exactamente la que hace falta para calcular quién ve qué. La segunda funciona porque las reglas de cubo son predicados baratos, evaluados una vez por cubo y no por cliente, lo que reduce el trabajo del evaluador sin eliminarlo. La tercera funciona porque un árbitro que solo ordena necesita muy poco del contenido, y con eso basta para tener puntos comunes de referencia sin exigir que nadie entienda la semántica. La cuarta funciona porque, al soldar las tres granularidades en el documento, el permiso se convierte en posesión de una clave y desaparece la necesidad de evaluador.
Hay además una celda que está poblada pero con cicatrices, y es muy instructiva: autoritativo, documentos, por consulta. Es posible consultar por el contenido de documentos, y existe una familia entera de productos que lleva décadas haciéndolo, pero solo al precio de que el servidor deje de tratar el documento como opaco y le construya índices por campo. Y en cuanto los construye, ha reintroducido por la puerta de atrás buena parte del modelo de filas. De ahí las restricciones que caracterizan a esa familia y que sus usuarios conocen de memoria: lenguajes de consulta recortados, índices obligatorios declarados de antemano y ausencia de junturas. No es una casilla vacía, es una casilla que se paga cara.
Las celdas vacías y por qué lo están
flowchart LR EV[cuanta evaluacion autoritativa de tu semantica admite el sistema] --> N[ninguna] EV --> M[solo el orden] EV --> A[completa] N --> N1[sin arbitro mas documentos mas pertenencia] M --> M1[registro ordenado mas filas mas alcance total] A --> A1[autoritativo mas filas mas consulta o coleccion] N --> V1[vacio: sin arbitro mas alcance por consulta] A --> V2[caro: autoritativo mas documentos opacos mas consulta] style N fill:#cba6f7,color:#11111b style M fill:#f9e2af,color:#11111b style A fill:#89b4fa,color:#11111b style V1 fill:#f38ba8,color:#11111b
La celda más claramente vacía es sin árbitro con alcance por consulta, y su vacío es una contradicción, no una ausencia. Mantener vivo el conjunto de filas que satisfacen un predicado exige que alguien tenga el conjunto completo de datos, evalúe la regla contra él y detecte las entradas y salidas conforme el estado cambia. Un participante sin árbitro tiene, por definición, una réplica parcial y ninguna autoridad para afirmar que su resultado es el resultado. Puede calcular qué elementos de lo que él tiene cumplen el predicado, que es una operación local perfectamente legítima, pero eso es filtrar, no delimitar alcance: nadie le puede decir qué le falta, porque nadie con esa información existe en el modelo. La casilla pide un evaluador a un sistema que se ha definido por no tener ninguno.
La segunda zona vacía, más matizada, es sin árbitro con filas. Aquí no hay una imposibilidad lógica y existen experimentos que dotan a un motor relacional de fusión convergente, así que la casilla no está prohibida. Lo que ocurre es que se queda sin motivo. La unidad de fila se elige por tres cosas: integridad referencial, invariantes declarativas y permisos por predicado. La primera y la segunda no sobreviven a la fusión, como estableció la segunda lección. La tercera exige evaluador, como estableció la tercera. Al retirar el árbitro se conserva la sintaxis de lo relacional y se pierden sus tres garantías, de modo que queda un modelo de datos con la incomodidad de las tablas y ninguna de sus ventajas. La casilla está casi vacía por falta de razones para habitarla, no por dificultad técnica.
La tercera es sin árbitro con alcance total, que existe pero solo en un rango de tamaño muy estrecho. Sin evaluador no hay forma de calcular qué subconjunto corresponde a cada participante, así que el alcance tiende naturalmente a lo que uno posee entero: todos los documentos cuya clave tienes. Eso es alcance por pertenencia, que se comporta como alcance por colección con las colecciones definidas por criptografía. La sincronización total genuina, entendida como bajarlo absolutamente todo, solo es viable en despliegues pequeños entre pares conocidos y deja de serlo en cuanto el conjunto compartido crece.
Una celda poblada no es mejor que una vacía ni una arquitectura es superior por estar en la zona más concurrida. La rejilla solo dice qué combinaciones son internamente coherentes, y coherente no significa adecuado para tu problema. Un sistema perfectamente coherente puede ser una elección pésima para tu dominio si tus invariantes o tus reglas de acceso viven en otra casilla, y ese diagnóstico lo dan las tres lecciones anteriores, no esta. Usa el mapa para descartar imposibles y para entender los compromisos de cada zona, nunca como escalafón.
El mapa que ordena el nivel siguiente
Con la rejilla en la mano, examinar un motor concreto deja de ser un ejercicio de lectura de documentación y pasa a ser un procedimiento de cuatro preguntas. ¿Puede el servidor rechazar una mutación por razones de negocio, y qué ve el usuario cuando lo hace? ¿Qué objeto lleva identidad, versión y permiso: la fila o el documento? ¿Quién recalcula la pertenencia al conjunto sincronizado, con qué frecuencia y a costa de quién? Y la cuarta, que es la que más deprisa separa lo maduro de lo prometedor: ¿cuánto tarda un dato en desaparecer de un dispositivo cuando su dueño pierde el permiso?
Ese procedimiento es lo que el nivel siguiente va a aplicar sistemáticamente, ya con nombres propios y con detalle de cada producto. Aquí se ha construido a propósito el mapa antes que el catálogo, porque el catálogo se mueve —el giro de ElectricSQL en 2024, cuando pasó a hacer llegar tablas de Postgres al cliente sin exigirle estructuras convergentes, es prueba suficiente de a qué velocidad— mientras que los ejes no se mueven, porque no salen del mercado sino de las restricciones del problema.
Si los tres ejes fueran independientes, las doce celdas estarían pobladas de forma más o menos uniforme y el vacío que acabamos de recorrer sería un accidente histórico a punto de corregirse. Están agrupadas en dos racimos alejados, y esa forma pide una explicación estructural. La explicación es que los tres ejes miden lo mismo desde tres sitios distintos, y esa magnitud única es cuánta evaluación autoritativa de tu semántica de aplicación admite la arquitectura. Míralo despacio, porque una vez visto no se puede dejar de ver. Que un servidor pueda rechazar una mutación significa que hay una parte con el estado completo, la identidad verificada y la disponibilidad necesaria para ejecutar tu regla de negocio y emitir un veredicto. Que el alcance se calcule por consulta significa que hay una parte con el estado completo, la identidad verificada y la disponibilidad necesaria para ejecutar tu predicado de lectura y decidir qué te corresponde. Que los permisos se expresen sobre filas mediante predicados significa que hay una parte con el estado completo, la identidad verificada y la disponibilidad necesaria para ejecutar tu regla de acceso. Son tres frases con la misma estructura y el mismo requisito: un evaluador. Los tres ejes no son tres decisiones sino tres manifestaciones de una sola, que es si existe o no ese evaluador y cuánto se le confía. De ahí se sigue inmediatamente todo lo demás. Las celdas vacías son las que piden evaluación sin evaluador —el caso de sin árbitro con alcance por consulta, que es directamente autocontradictorio— o las que pagan un evaluador y luego renuncian a usar sus garantías, que es el caso de sin árbitro con filas y explica por qué esa combinación no encuentra habitantes aunque nadie la prohíba. Y las celdas pobladas son las coherentes a lo largo de esa magnitud: si aceptas evaluador, lo aprovechas en los tres sitios y llegas a filas con consultas o cubos y mutaciones arbitradas; si lo rechazas, lo rechazas en los tres y llegas a documentos con permisos por clave y alcance por pertenencia. Los racimos no son dos escuelas de pensamiento compitiendo: son los dos extremos coherentes de una única recta. La utilidad inmediata de esta reducción es que te da una prueba de falsedad aplicable en treinta segundos a cualquier motor que se anuncie de aquí en adelante, y funcionará también con los que aún no existen. Cuando alguien prometa simultáneamente descentralización sin servidor, consultas vivas de grano fino sobre el conjunto completo y permisos por predicado, no estás ante una innovación que rompe el compromiso: estás ante una de dos cosas, y solo dos. O hay un servidor en la arquitectura al que se ha dejado de llamar servidor, lo cual es habitual y perfectamente legítimo siempre que se diga. O alguno de esos tres términos se está usando con un significado más flojo del que aparenta, y lo más frecuente es que sea el segundo: consultas que en realidad filtran lo que ya tienes en local en lugar de delimitar lo que baja. Pregunta cuál de las dos es, con esas palabras, y observa la respuesta. La calidad de esa respuesta te dirá en un minuto más sobre la madurez del proyecto que una semana leyendo su documentación.
- Dibuja la rejilla de doce celdas y coloca en ella los cinco sistemas nombrados en este nivel, marcando cuáles ocupan dos casillas a la vez.
- Sitúa tu propia aplicación actual, la que ya tienes en producción, en la celda que le corresponde según lo que su código hace y no según lo que dice su documento de arquitectura.
- Comprueba si tu posición es coherente a lo largo del eje único, es decir, si estás pagando un evaluador y aprovechándolo en los tres frentes o prescindiendo de él en los tres.
- Aplica las cuatro preguntas del procedimiento a un motor que estés considerando y anota cuáles no puedes responder con su documentación.
- Busca un producto que prometa la combinación imposible y averigua cuál de las dos explicaciones es la suya.
- Escribe en un párrafo qué celda debería ocupar tu próxima aplicación y qué invariante o qué regla de acceso concreta te obliga a ello.