⏱️ Lectura: 11 min

Cuando dos personas editan el mismo archivo en Figma al mismo tiempo, sus cambios se fusionan sin que nadie pise el trabajo del otro. Cuando marcás una tarea como hecha en Linear estando sin conexión en un avión y al mismo tiempo un compañero la reasigna desde otro país, ambas operaciones sobreviven al reconectarse. Esa experiencia —colaborar con gente en tiempo real, sin servidores que bloqueen, sin pantallas pidiendo resolver conflictos— no es magia: detrás hay una familia de estructuras de datos llamada CRDTs (Conflict-free Replicated Data Types) que convirtió la edición colaborativa en una feature resuelta, no en un campo minado.

📑 En este artículo
  1. Qué son los CRDTs y por qué importan
  2. Cómo funcionan los CRDTs por dentro
    1. State-based (CvRDT)
    2. Operation-based (CmRDT)
  3. Ejemplos prácticos con código
    1. Un contador distribuido (G-Counter)
    2. Last-Write-Wins Register
    3. Un conjunto sin eliminaciones fantasma (OR-Set)
  4. Casos de uso reales en 2026
  5. Ventajas y desventajas
    1. Ventajas
    2. Desventajas
  6. Preguntas frecuentes
    1. ¿Los CRDTs reemplazan a una base de datos?
    2. ¿Son más lentos que una base de datos normal?
    3. ¿CRDT o Operational Transformation (OT)?
    4. ¿Puedo usarlos en apps sin red en tiempo real?
    5. ¿Cómo resuelven el orden en texto colaborativo?
    6. ¿Existe riesgo de inconsistencia permanente?
  7. Referencias

En esta guía vamos a explicar qué son los CRDTs en 2026, por qué se volvieron el estándar de facto para apps colaborativas, cómo funcionan matemáticamente, qué código real los implementa y cuándo no deberías usarlos. Al final vas a entender por qué Figma, Linear, Notion, Obsidian Sync y decenas de herramientas nuevas construyeron sus motores de sincronización sobre esta abstracción en lugar de apoyarse en bases de datos tradicionales.

Qué son los CRDTs y por qué importan

Un CRDT es una estructura de datos replicada —es decir, que existe simultáneamente en múltiples nodos o clientes— diseñada para que todas las copias converjan al mismo estado sin necesidad de un coordinador central. La sigla viene del inglés Conflict-free Replicated Data Type, y la palabra importante es la primera: conflict-free. No es que el sistema detecte conflictos y los resuelva después; es que, por construcción matemática, los conflictos no pueden existir.

El término fue formalizado en 2011 por Marc Shapiro, Nuno Preguiça, Carlos Baquero y Marek Zawirski en un paper del INRIA. Ese trabajo demostró cómo diseñar tipos cuyas operaciones cumplen tres propiedades matemáticas clave: son conmutativas (el orden en que se aplican no cambia el resultado), asociativas (la forma de agrupar operaciones tampoco) e idempotentes (aplicar dos veces la misma operación produce el mismo estado que aplicarla una vez). Con esas tres garantías, fusionar los cambios de cualquier réplica en cualquier orden siempre converge al mismo valor final.

En la práctica, los CRDTs son lo que permite editar offline, reconciliar después, tolerar latencias altas y sobrevivir particiones de red sin bloquear al usuario. Son la contracara de los sistemas CP del teorema CAP: los CRDTs eligen disponibilidad y tolerancia a particiones, sacrificando la consistencia fuerte por una versión más débil pero más útil llamada Strong Eventual Consistency (SEC). La promesa es simple: si todas las réplicas recibieron las mismas operaciones, da igual en qué orden, ven exactamente lo mismo.

💭 Clave: Un CRDT no evita conflictos porque los resuelva rápido, sino porque redefine qué significa un conflicto. Si dos usuarios escriben sobre la misma celda, ambas escrituras se aceptan y el resultado es determinista para todos.
CRDTs sincronizando ediciones entre clientes distribuidos
Cada réplica aplica operaciones localmente y converge sin coordinador.

Cómo funcionan los CRDTs por dentro

Hay dos grandes familias de CRDTs: los state-based (CvRDT) y los operation-based (CmRDT). Ambos llegan al mismo destino —convergencia sin coordinación— pero por caminos distintos, y entender la diferencia es el paso más importante para saber cuándo usar uno u otro.

State-based (CvRDT)

En los CRDTs basados en estado, cada réplica mantiene su copia completa del valor y periódicamente la envía entera a las otras. Cuando una réplica recibe el estado de otra, aplica una función merge que combina ambas copias. Para que el sistema converja, esa función debe ser un join semilattice: conmutativa, asociativa e idempotente. La ventaja es que tolera cualquier cosa —mensajes duplicados, reordenados, perdidos— siempre que eventualmente llegue al menos uno. La desventaja es el tamaño: enviar el estado completo cada vez no escala en documentos grandes.

Operation-based (CmRDT)

En los CRDTs basados en operaciones, las réplicas propagan cada cambio individual —un insert, un delete, un increment— en lugar del estado completo. Para que converjan, las operaciones deben ser conmutativas entre sí y cada réplica debe recibir todas exactamente una vez. Esto requiere un canal de comunicación confiable (reliable broadcast) o un mecanismo de deduplicación, pero a cambio los mensajes son diminutos. Yjs, Automerge y las implementaciones modernas usan variantes de este enfoque, a menudo combinadas con compactación periódica.

En 2026 la mayoría de librerías de producción son híbridas: usan operaciones para la red en caliente, pero permiten snapshots de estado para sincronización inicial o para clientes que se quedaron offline por mucho tiempo.

sequenceDiagram
    participant A as Cliente A
    participant B as Cliente B
    participant C as Cliente C
    A->>B: op1: insert("H", pos=0)
    A->>C: op1: insert("H", pos=0)
    B->>A: op2: insert("i", pos=1)
    B->>C: op2: insert("i", pos=1)
    C->>A: op3: insert("!", pos=2)
    C->>B: op3: insert("!", pos=2)
    Note over A,C: Los tres clientes convergen a "Hi!"

Ejemplos prácticos con código

Un contador distribuido (G-Counter)

El CRDT más simple es el G-Counter, un contador que solo crece. Cada réplica tiene un slot propio y puede incrementar solo el suyo. Para leer el valor total, se suman todos los slots. Para fusionar, se toma el máximo por slot. Es conmutativo, asociativo e idempotente por construcción.

class GCounter {
  constructor(nodeId) {
    this.nodeId = nodeId;
    this.counts = {};
  }

  increment(n = 1) {
    this.counts[this.nodeId] = (this.counts[this.nodeId] || 0) + n;
  }

  value() {
    return Object.values(this.counts).reduce((a, b) => a + b, 0);
  }

  merge(other) {
    for (const node of Object.keys(other.counts)) {
      this.counts[node] = Math.max(
        this.counts[node] || 0,
        other.counts[node]
      );
    }
  }
}

Con 15 líneas ya tenés un contador que tres servidores pueden incrementar sin coordinarse y que eventualmente muestra el mismo valor en todos. Es el hola mundo de los CRDTs.

Last-Write-Wins Register

Un LWW-Register guarda un valor único y, cuando hay dos escrituras concurrentes, gana la que tiene el timestamp más alto. Es el CRDT que usa Cassandra internamente para resolver escrituras conflictivas. Simple de implementar, pero ojo: perder datos por un reloj desincronizado es real. Por eso los sistemas serios usan relojes lógicos tipo Lamport o HLC en lugar de Date.now().

Un conjunto sin eliminaciones fantasma (OR-Set)

El Observed-Remove Set resuelve el problema clásico de los conjuntos: si un usuario agrega un elemento y otro lo elimina al mismo tiempo, ¿cuál gana? En OR-Set cada adición se etiqueta con un tag único, y eliminar solo afecta a los tags que la réplica ya había observado. Si llega una adición nueva concurrente con un delete, la adición sobrevive. Es la base del tipo Set de Yjs y del Orset de Riak.

Editor colaborativo mostrando múltiples cursores en tiempo real
Yjs y Automerge son los motores que alimentan editores colaborativos modernos.

Casos de uso reales en 2026

Figma fue uno de los primeros casos públicos de CRDTs a escala: su documento vectorial es un árbol replicado con operaciones conmutativas para mover, redimensionar y asignar propiedades. El post técnico de Evan Wallace en 2019 explicando el diseño sigue siendo lectura obligatoria y muestra cómo combinaron CRDTs para el árbol con last-write-wins por propiedad.

Linear, Height y Notion usan sincronización local-first basada en CRDTs o estructuras equivalentes para permitir uso offline sin bloquear la UI. La experiencia de escribir una tarea y ver cómo aparece instantáneamente en el cliente del compañero —sin loading spinners— depende directamente de esta tecnología.

Yjs y Automerge son las dos librerías open source dominantes. Yjs se enfoca en performance bruta y tiene adaptadores para ProseMirror, CodeMirror, Monaco y Tiptap. Automerge apunta más al modelo mental de JSON local-first, con tiempo histórico reversible gratis. Ambas corren en navegador, Node y Rust.

También existen CRDTs en bases de datos: Riak expone contadores, sets y maps CRDT como tipos nativos. Redis Enterprise Active-Active usa CRDTs para sincronizar clusters multi-región. Y AntidoteDB es un sistema SQL-CRDT experimental pensado para geo-distribución.

💡 Tip: Si tu app necesita colaboración en tiempo real sobre texto estructurado, empezá con Yjs. Ya tiene integración con los editores más populares y un ecosistema de proveedores de red (WebRTC, WebSocket, y-websocket) listos para producción.

Ventajas y desventajas

Ventajas

  • Offline-first real: la app sigue funcionando sin conexión y sincroniza al reconectarse, sin flujos de resolución manual.
  • Latencia percibida cero: los cambios locales se aplican al instante, sin esperar al servidor.
  • Sin coordinador central: cualquier nodo puede aceptar escrituras, lo que habilita arquitecturas P2P y multi-region activas.
  • Determinismo: el estado final depende solo del conjunto de operaciones, no del orden de llegada ni de la red.
  • Auditabilidad: muchas implementaciones conservan historia, lo que habilita undo/redo distribuido y time-travel.

Desventajas

  • Metadata overhead: los tags, vectores de versión y tombstones ocupan espacio. Un set de 1000 elementos puede pesar varios MB si hay muchas ediciones históricas.
  • Compactación compleja: eliminar metadata vieja sin romper la convergencia es un problema de sistemas distribuidos difícil, y la mayoría de librerías lo hacen solo parcialmente.
  • Semántica restringida: no podés implementar cualquier operación. Reservar un inventario único, por ejemplo, necesita consenso (Raft, Paxos), no CRDTs.
  • Consistencia eventual, no fuerte: si tu dominio necesita que una operación sea globalmente visible antes de continuar (pagos, saldos, claims únicos), CRDTs no aplica.
  • Curva de aprendizaje: modelar bien tu dominio como CRDT requiere pensar distinto. Un árbol CRDT no es un árbol tradicional y las operaciones mueven indices de forma no obvia.

📖 Resumen en Telegram: Ver resumen

Preguntas frecuentes

¿Los CRDTs reemplazan a una base de datos?

No. Los CRDTs son estructuras de datos, no un sistema de almacenamiento completo. Podés combinarlos con Postgres, SQLite, IndexedDB o cualquier store: la base guarda el estado serializado y el CRDT gestiona cómo se fusionan cambios.

¿Son más lentos que una base de datos normal?

Para escrituras individuales son comparables o más rápidos porque no requieren roundtrip. Para lecturas masivas pueden ser más lentos si la metadata está muy fragmentada. La mayoría de implementaciones modernas (Yjs, Automerge 2.0) resuelven esto con índices y compactación, y cargan documentos de miles de ediciones en milisegundos.

¿CRDT o Operational Transformation (OT)?

OT fue la técnica usada por Google Docs durante más de una década. Funciona bien pero requiere un servidor que transforme operaciones en orden. Los CRDTs son más simples de razonar matemáticamente, funcionan P2P sin coordinador y ganaron tracción en apps nuevas. En 2026, equipos nuevos eligen CRDTs por defecto.

¿Puedo usarlos en apps sin red en tiempo real?

Sí. Aunque se asocian con colaboración en vivo, los CRDTs también sirven para sync entre dispositivos del mismo usuario, backups incrementales o replicación geográfica. Obsidian Sync es un ejemplo: no hay colaboración multiusuario, pero Yjs mantiene tus notas consistentes entre laptop, móvil y tablet.

¿Cómo resuelven el orden en texto colaborativo?

Los CRDTs de texto (RGA, LSEQ, YATA) asignan a cada carácter un identificador único y posicional que preserva el orden independientemente de quién lo insertó. Yjs usa YATA, que optimiza inserciones consecutivas y logra documentos con cientos de miles de caracteres sin latencia perceptible.

¿Existe riesgo de inconsistencia permanente?

Si se cumplen las propiedades algebraicas y todas las operaciones eventualmente se propagan, no. El riesgo real viene de bugs de implementación, timestamps rotos o pérdida silenciosa de mensajes. Por eso en producción se suelen complementar con checksums de estado y pruebas de convergencia aleatoria (property-based testing).

Referencias

📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.


Andrés Morales

Desarrollador e investigador en inteligencia artificial. Escribe sobre modelos de lenguaje, frameworks, herramientas para devs y lanzamientos open source. Cubre papers de ML, ecosistema de startups tech y tendencias de programación.

0 Comentarios

Deja un comentario

Marcador de posición del avatar

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.