El árbol de decisión: de un producto concreto a una arquitectura
Una guía practicable que empieza preguntando si el producto necesita autoridad central y baja rama a rama hasta la elección concreta de almacén local, motor de convergencia y transporte.
La lección anterior comprimió el recorrido en cuatro ideas; esta lo convierte en un procedimiento. Un árbol de decisión no es una tabla comparativa disfrazada: su virtud está en el orden de las preguntas, porque cada respuesta poda ramas enteras y hace irrelevantes discusiones que, planteadas fuera de orden, consumen semanas de equipo. La regla que organiza todo lo que sigue es que las preguntas caras se hacen primero y las baratas al final, donde caro significa que la respuesta condiciona el modelo de datos y barato significa que se puede cambiar más adelante sin reescribir nada. Casi todos los desastres de arquitectura que este campo produce vienen de haber empezado por la última pregunta del árbol: qué biblioteca usamos.
- Ordenar las decisiones de una arquitectura local-first de la más cara a la más reversible.
- Resolver la pregunta raíz sobre autoridad central por entidad y no por producto entero.
- Encadenar forma de los datos, volumen y perfil de dispositivo hasta una elección concreta.
- Distinguir qué decisiones condicionan el modelo de datos y cuáles son sustituibles después.
- Documentar el recorrido del árbol como un registro de decisión defendible ante el equipo.
La pregunta raíz: qué entidades necesitan que alguien diga que sí
La primera bifurcación no es si el producto va a ser local-first. Es qué partes del producto exigen que exista un punto único capaz de aceptar o rechazar una operación antes de que se considere ocurrida. Formulada así, la pregunta casi nunca se responde con un sí o un no global, y ese es precisamente su valor.
Hay tres familias donde el arbitraje es irrenunciable y conviene reconocerlas de inmediato. La primera es la exclusividad: el último asiento del avión, el nombre de usuario libre, el número de serie irrepetible. Ninguna operación conmutativa puede fabricar unicidad global, porque la unicidad es exactamente la propiedad de que dos operaciones concurrentes no puedan ambas tener éxito. La segunda es el efecto externo irreversible: cobrar una tarjeta, enviar un correo, abrir una puerta. Aquí el problema no es la convergencia de los datos sino que el mundo no tiene deshacer. La tercera es la regla que un tercero debe poder auditar: cumplimiento normativo, límites de gasto, permisos que un administrador tiene que poder aplicar y demostrar.
Todo lo que no cae en esas tres familias es candidato a converger. Y esa lista suele ser sorprendentemente larga: el contenido de los documentos, el estado de las tareas, las anotaciones, las preferencias, las etiquetas, el orden de una lista, los borradores. En la mayoría de los productos, entre el ochenta y el noventa y cinco por ciento de las escrituras que un usuario genera no necesitan que nadie las autorice.
flowchart TD
Q0{Esta entidad exige exclusividad efecto externo o auditoria de un tercero} -->|si| A[Autoridad central para esta entidad]
Q0 -->|no| Q1{El usuario debe poder trabajar sin red}
A --> A1[Servidor con transaccion y escritura optimista en el cliente]
Q1 -->|no| B[Cache optimista sobre el servidor y nada mas]
Q1 -->|si| Q2{Habra edicion concurrente sobre el mismo objeto}
Q2 -->|no| C[Replica local con cola de operaciones y resolucion simple]
Q2 -->|si| D[Convergencia garantizada por la estructura de datos]
style D fill:#a6e3a1,color:#11111b
style A fill:#f38ba8,color:#11111bUn producto serio casi siempre termina con dos regímenes conviviendo: un subconjunto pequeño de entidades con autoridad en el servidor y transacciones clásicas, y el grueso del modelo replicado y convergente. El error frecuente no es mezclar, es no haber decidido dónde está la frontera y descubrirla tarde. Escribir esa frontera en una sola hoja, entidad por entidad, es el artefacto de diseño más rentable de todo este árbol.
La segunda bifurcación: la forma de los datos manda
Resuelta la raíz, la siguiente pregunta cara no es qué biblioteca sino qué forma tienen los datos que van a converger, porque esa forma determina qué familia de solución es siquiera aplicable.
Si el dato es texto libre editado carácter a carácter por varias personas a la vez, se está en el caso más exigente del campo y hace falta un tipo secuencia con garantías de no intercalación. Todo lo que el track dedicó a RGA, a la intercalación destapada en 2019 y a los algoritmos posteriores existe para este caso y solo para este caso. Si el dato es un grafo de objetos con campos, como tareas, tarjetas o entidades de negocio, basta con mapas y registros compuestos, que son mucho más baratos y mucho más fáciles de razonar. Si el dato es relacional con consultas sobre conjuntos grandes, la respuesta natural deja de ser un documento convergente y pasa a ser un motor de sincronización sobre tablas. Y si el dato es un fichero binario grande, el problema no es de convergencia sino de direccionamiento por contenido, troceado y transferencia.
Esta bifurcación explica una confusión muy extendida. Discutir en abstracto si es mejor un motor de documentos o uno de tablas es una discusión sin respuesta porque la pregunta está mal planteada: un editor colaborativo y un panel de control con filtros sobre cien mil filas no compiten por la misma solución, y un producto que tenga las dos cosas necesitará las dos.
Texto colaborativo
Secuencia replicada con garantías de intercalación. Es el caso donde la elección de algoritmo importa de verdad y donde el ecosistema está más maduro.
Objetos con campos
Mapas y registros compuestos. Barato, predecible y suficiente para la enorme mayoría de las aplicaciones que no editan prosa.
Relacional con consultas
Motor de sincronización sobre tablas, con la autoridad todavía en una base central y el cliente manteniendo una porción consultable.
Binario grande
Direccionamiento por contenido, troceado y verificación. Aquí el problema es transferencia y deduplicación, no fusión.
La tercera: cuánto dato, en qué dispositivo y durante cuánto tiempo
La tercera pregunta es de volumen, y se responde con tres números medidos, no estimados. El primero es el tamaño del conjunto de trabajo que un usuario necesita tener disponible sin red, que casi nunca es la base entera y que conviene acotar por proyecto, por espacio o por ventana temporal. El segundo es el crecimiento del historial, porque un modelo convergente acumula metadatos de causalidad y no es lo mismo un documento con diez mil operaciones que uno con diez millones. El tercero es el perfil del dispositivo más modesto que el producto va a tocar, medido en memoria disponible y en velocidad de almacenamiento, no en año de fabricación.
De estos tres números salen las decisiones que más tarde son irreversibles. Si el conjunto de trabajo no cabe, hay que introducir sincronización parcial desde el primer día, y eso condiciona el modelo de datos entero porque obliga a que las unidades de sincronización sean explícitas y a que el sistema sepa razonar sobre lo que no tiene. Si el historial crece rápido, hay que diseñar compactación antes de tener usuarios, porque después habrá dispositivos con historia antigua a los que no se puede dejar atrás. Y si el dispositivo modesto es de verdad modesto, la elección de almacén local queda decidida por el arranque en frío mucho antes que por cualquier otra consideración.
// Las tres medidas que deciden la rama, tomadas antes de elegir biblioteca.
const t0 = performance.now();
await abrirReplica(idUsuario); // arranque en frio real
const arranqueMs = performance.now() - t0;
const bytesEnCaliente = await medirMemoriaDelDocumento();
const opsHistorial = await contarOperaciones();
const cuota = await navigator.storage.estimate();
// Criterio: si arranqueMs supera el presupuesto de interaccion del producto
// en el dispositivo mas modesto, la rama de replica completa esta descartada.
La trampa más común de este nivel del árbol es medir con el volumen del prototipo. Genera un conjunto sintético equivalente a un usuario intenso después de tres años, con su historial completo, y repite las tres medidas. La diferencia entre ambas mediciones suele ser de uno o dos órdenes de magnitud, y es la que decide si el diseño necesita compactación y sincronización parcial desde el principio o puede permitirse aplazarlas.
De la rama a la elección concreta, que es lo último y lo más reversible
Solo ahora tiene sentido nombrar herramientas, y conviene hacerlo entendiendo que esta es la decisión más fácil de revertir de todo el árbol. Cambiar de biblioteca de convergencia dolerá semanas; cambiar la frontera de autoridad o la unidad de sincronización dolerá trimestres.
Para el almacén local el criterio es el tipo de acceso. Si el producto consulta por clave y rangos y el volumen es moderado, IndexedDB con un envoltorio decente es suficiente y evita una pila entera de complejidad. Si el producto necesita consultas de verdad sobre conjuntos grandes, SQLite compilado a WebAssembly sobre el sistema de ficheros del origen, dentro de un worker y con elección de líder entre pestañas, es la respuesta madura. Si el producto es analítico sobre columnas, hay motores específicos que ganan por un margen amplio.
Para la convergencia el criterio es la forma de los datos de la segunda bifurcación, cruzada con la madurez que el proyecto exija. Yjs sigue siendo el estándar de facto para edición de texto y tiene el ecosistema más ancho de proveedores y editores. Automerge, con su versión 3.0 de julio de 2025, redujo el consumo de memoria más de diez veces respecto a la anterior y con ello despejó la objeción principal que se le hacía, quedando como la opción natural cuando la historia completa y el viaje en el tiempo son parte del producto. Loro apuesta por texto enriquecido y árboles con movimiento desde una implementación en Rust. Y si el modelo es relacional, la conversación se traslada a los motores de sincronización, donde Zero alcanzó su versión 1.0 en junio de 2026 y convive con propuestas que reparten de forma distinta la autoridad entre servidor y cliente.
Para el transporte el criterio es quién tiene que poder hablar con quién. La mayoría de los productos no necesitan conexiones directas entre clientes y les basta un servidor de relevo, que además simplifica la operación y el control de acceso. Cuando la topología entre iguales sí es un requisito, el ecosistema tiene hoy una respuesta operable: iroh publicó su versión 1.0 el 15 de junio de 2026 sobre QUIC con claves públicas como direcciones, y esa combinación evita buena parte del peso de la pila diseñada originalmente para vídeo.
Antes de bajar por el árbol completo, evalúa honestamente la rama corta: escritura optimista en el cliente sobre un servidor con autoridad, sin convergencia y sin réplica completa. Cubre el ideal de latencia percibida, cuesta una fracción del esfuerzo y es reversible. Si el producto no necesita edición concurrente real ni trabajo sin red prolongado, bajar por la rama larga es comprar una factura de mantenimiento a cambio de propiedades que nadie va a usar. Elegir la rama corta con conocimiento de causa es una decisión de ingeniería madura, no una renuncia.
La tentación al terminar un recorrido como este es buscar la recomendación: qué biblioteca, qué motor, qué transporte. Y esa es exactamente la pregunta que menos importa, porque su respuesta caduca en dieciocho meses mientras que el orden en que se hacen las preguntas no ha cambiado en veinte años y no va a cambiar. La primera pregunta es de topología de la autoridad y se responde por entidad, produciendo dos listas que ningún argumento posterior debería mover: lo que exige que alguien diga que sí, y lo que puede converger solo. La segunda es de forma del dato, y decide qué familia de solución es siquiera aplicable, cerrando de golpe discusiones que en abstracto no tienen respuesta. La tercera es de volumen medido en el dispositivo peor, y es la que determina si hace falta sincronización parcial y compactación desde el primer día o si se pueden aplazar, que es la diferencia entre un rediseño barato y uno imposible. Y solo la cuarta es de herramienta, que es la más ruidosa, la más discutida en público y la única que se puede cambiar sin tocar el modelo de datos. El valor de recorrer el árbol en este orden no está en llegar a una hoja concreta, sino en que cada respuesta deja por escrito una restricción que el equipo puede defender seis meses después, cuando alguien proponga añadir un identificador asignado por el servidor porque simplifica un caso, o un contador global porque el informe lo pide, o una búsqueda remota porque ahorra tres semanas. Cada una de esas propuestas es razonable por separado; la suma de todas ellas es la deriva silenciosa que convierte una arquitectura local-first en una aplicación de nube con una caché grande. Un árbol de decisión escrito no impide esa deriva, pero la vuelve visible: obliga a que quien la propone diga en voz alta qué rama está reabriendo y qué se compra a cambio. Eso, y no la elección de motor, es lo que separa un sistema que envejece bien de uno que se reescribe.
- Elige un producto que conozcas y escribe sus entidades en dos columnas según exijan arbitraje o puedan converger.
- Clasifica cada entidad convergente en una de las cuatro formas de dato y justifica la clasificación en una línea.
- Genera un conjunto sintético del año tres y mide arranque en frío, memoria en caliente y crecimiento del historial.
- Recorre el árbol hasta una hoja y anota qué rama descartaste en cada nivel y con qué evidencia.
- Evalúa en serio la rama corta y escribe el argumento por el que la descartas, o acéptala.
- Convierte el recorrido en un registro de decisión de una página y ponle fecha de revisión.