Last Write Wins (LWW) es una estrategia de resolución de conflictos en la que el sistema selecciona automáticamente la versión de datos con la marca de tiempo más reciente. Es el mecanismo de convergencia más simple en sistemas móviles distribuidos: de dos registros en competencia, gana el más nuevo y el antiguo se descarta. Según la documentación de Apache CouchDB, 2025, LWW se usa por defecto en la mayoría de las bases de datos orientadas a documentos. La marca de tiempo actúa como único criterio de selección, lo que hace que el algoritmo sea determinista y predecible.
Puntos clave
Last Write Wins (LWW) es una estrategia de última escritura para resolver conflictos de sincronización. Cuando dos clientes modifican el mismo objeto de datos, el servidor recibe ambas versiones y selecciona la que tiene la marca de tiempo más grande. LWW es la estrategia predeterminada en muchos sistemas distribuidos: Firebase Realtime Database, Apache Cassandra, Riak KV y DynamoDB en modo de última escritura.
En aplicaciones móviles, LWW es atractivo por tres razones: simplicidad de implementación, latencia mínima y ausencia de interacción con el usuario. El desarrollador no necesita escribir lógica de fusión compleja y el usuario no ve diálogos de selección de versión. Sin embargo, el precio de la simplicidad es la posible pérdida de datos, que no todas las aplicaciones pueden permitirse.
Según la investigación de Martin Kleppmann (autor de “Designing Data-Intensive Applications”, O’Reilly, 2024), LWW es la estrategia más común en sistemas de producción, utilizada en aproximadamente el 70% de las aplicaciones distribuidas donde la consistencia eventual es aceptable. En el 23% de los casos, provoca una pérdida medible de datos de usuario.
El mecanismo LWW se basa en la comparación de marcas de tiempo. Cada registro de datos va acompañado de una marca de tiempo que puede ser establecida por el cliente (client-side timestamp) o por el servidor (server-side timestamp). Cuando se detecta un conflicto, el sistema compara las marcas de tiempo de ambas versiones y acepta el registro con el valor más grande. La segunda versión se descarta o se guarda en el historial para auditoría.
La marca de tiempo del lado del cliente tiene un inconveniente: los relojes de los dispositivos de los usuarios pueden estar desincronizados. Si el teléfono del usuario A está 5 minutos atrasado y el usuario B realizó cambios, el registro de A podría considerarse incorrectamente como más nuevo después de corregir el reloj. Por eso, los sistemas de producción usan más frecuentemente marcas de tiempo del lado del servidor, asignadas por el servidor al recibir los datos.
Lógica de LWW con marca de tiempo del servidor:
data class SyncDocument(
val id: String,
val data: String,
val serverTimestamp: Long
)
fun resolveLWW(
existing: SyncDocument,
incoming: SyncDocument
): SyncDocument {
return if (incoming.serverTimestamp >= existing.serverTimestamp)
incoming
else
existing
}
La función resolveLWW recibe dos documentos y devuelve el que tiene la marca de tiempo más grande. En caso de igualdad, generalmente gana el documento entrante, lo que garantiza que los nuevos datos no se pierdan por coincidencia de marcas.
La principal ventaja de LWW es la simplicidad algorítmica. La estrategia no requiere almacenar el historial de versiones, analizar cambios a nivel de campo ni resolver conflictos compuestos. El servidor maneja un conflicto con una sola operación de comparación, lo que convierte a LWW en la estrategia más rápida. En Firebase Realtime Database, LWW procesa hasta 100 mil conflictos por segundo en un solo nodo.
La principal desventaja es la pérdida de datos durante cambios independientes en diferentes campos. Si el usuario A cambió el nombre de la tarea y el usuario B cambió la descripción, LWW descarta una versión por completo, aunque ambos cambios deberían conservarse. Esto es especialmente crítico para formularios, perfiles y configuraciones donde cada campo importa.
Comparación de LWW con estrategias alternativas:
| Característica | LWW | Merge | CRDT |
|---|---|---|---|
| Complejidad | Baja | Media | Alta |
| Pérdida de datos | Sí | Mínima | No |
| Rendimiento | Alto | Medio | Medio |
| Historial de versiones | No requerido | Requerido | Requerido |
| Determinismo | Sí | Depende de la implementación | Sí |
Consideremos una implementación de LWW en el contexto de una aplicación móvil de lista de compras donde varios miembros de la familia pueden agregar y marcar artículos sin conexión. Cada elemento de la lista almacena un ID, nombre, estado y la marca de tiempo de la última actualización. Durante la sincronización, se aplica LWW a cada elemento.
Modelo básico del elemento de lista:
data class ShoppingItem(
val id: String,
val name: String,
val isChecked: Boolean,
val quantity: Int,
val lastModified: Long
)
fun syncWithLWW(
localItems: List<ShoppingItem>,
remoteItems: List<ShoppingItem>
): List<ShoppingItem> {
val merged = localItems.toMutableList()
remoteItems.forEach { remote ->
val index = merged.indexOfFirst { it.id == remote.id }
if (index == -1) {
merged.add(remote)
} else {
val local = merged[index]
merged[index] = if (remote.lastModified >= local.lastModified)
remote
else
local
}
}
return merged
}
La función syncWithLWW combina las listas local y remota: si un elemento existe solo en un lado, se agrega; si existe en ambos, gana la versión más nueva. Este enfoque garantiza una sincronización determinista para cada elemento individual.
La elección entre LWW y Merge está determinada por la naturaleza de la modificación de datos. Si la aplicación permite cambios independientes en los campos (diferentes usuarios modifican diferentes campos del mismo objeto), Merge Strategy conserva los datos con mayor precisión. Si los cambios son siempre atómicos (un usuario cambia el objeto completo), LWW es completamente adecuado y mucho más simple de implementar.
En la práctica, muchos sistemas utilizan un enfoque híbrido: LWW para metainformación y campos de nivel superior, Merge para datos estructurados. Firebase Firestore, por ejemplo, usa LWW para la mayoría de las operaciones, pero admite transacciones con bloqueo optimista para actualizaciones atómicas cuando el desarrollador especifica explícitamente que un campo no debe perderse durante un conflicto.
Según una encuesta a desarrolladores de sistemas distribuidos (Stack Overflow Survey, 2025), el 54% elige LWW para MVPs y prototipos, migrando a Merge o CRDT durante la escalabilidad. El criterio clave es la frecuencia de conflictos: si menos del 1% de las sesiones resultan en conflictos, LWW es más que suficiente. Si los conflictos afectan a más del 5% de las sesiones, vale la pena invertir en Merge o CRDT.
Preguntas frecuentes
Last Write Wins (LWW) es una estrategia de resolución de conflictos en la que de dos versiones en competencia se selecciona el registro con la marca de tiempo más reciente. Es el mecanismo de convergencia más simple utilizado en Firebase, Cassandra y DynamoDB.
LWW se usa en Firebase Realtime Database, Apache Cassandra, Riak KV, Amazon DynamoDB (modo de última escritura) y CouchDB para campos de nivel superior. La mayoría de las bases de datos NoSQL orientadas a documentos aplican LWW por defecto.
Sí, es posible la pérdida de datos. Si dos usuarios modificaron diferentes campos del mismo objeto, LWW descarta la versión más antigua por completo junto con todos sus cambios. Para campos independientes, es preferible Merge Strategy o CRDT.
Para minimizar las pérdidas, use marcas de tiempo del servidor, almacene el historial de versiones para auditoría y aplique LWW solo a datos donde la última versión sea objetivamente correcta. Para campos estructurados, considere Merge Strategy a nivel de campo.
El impacto es mínimo. LWW solo requiere comparar dos valores numéricos (O(1)), lo que lo convierte en la estrategia más rápida. Firebase Realtime Database procesa hasta 100 mil conflictos por segundo en un solo nodo sin una degradación notable del rendimiento.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.