Last Write Wins (LWW) — strategie řešení konfliktů, při které systém automaticky vybírá verzi dat s nejnovějším časovým razítkem. Je to nejjednodušší mechanismus konvergence v distribuovaných mobilních systémech: ze dvou konkurenčních záznamů vítězí ten novější a starší je zahozen. Podle Apache CouchDB documentation, 2025 je LWW standardně používán ve většině databází orientovaných na dokumenty. Časové razítko je jediným kritériem výběru, což činí algoritmus deterministickým a předvídatelným.
Hlavní body
Last Write Wins (LWW) — je strategie posledního zápisu při řešení synchronizačních konfliktů. Když dva klienti změní stejný datový objekt, server obdrží obě verze a vybere tu s větším časovým razítkem (timestamp). LWW je výchozí strategií v mnoha distribuovaných systémech: Firebase Realtime Database, Apache Cassandra, Riak KV a DynamoDB v režimu posledního zápisu.
V mobilních aplikacích je LWW atraktivní ze tří důvodů: jednoduchost implementace, minimální latence a žádná interakce s uživatelem. Vývojář nemusí psát složitou logiku slučování a uživatel nevidí dialogy pro výběr verze. Cenou za jednoduchost je však potenciální ztráta dat, kterou si ne všechny aplikace mohou dovolit.
Podle výzkumu Martina Kleppmanna (autora knihy „Designing Data-Intensive Applications”, O’Reilly, 2024) je LWW nejrozšířenější strategií v produkčních systémech, používaná přibližně v 70 % distribuovaných aplikací, kde je přijatelná výsledná konzistence (eventual consistency). Ve 23 % případů vede k měřitelné ztrátě uživatelských dat.
Mechanismus LWW je založen na porovnávání časových razítek. Každý záznam dat je doprovázen timestampem, který může být nastaven klientem (client-side timestamp) nebo serverem (server-side timestamp). Při detekci konfliktu systém porovná timestampy obou verzí a přijme záznam s vyšší hodnotou. Druhá verze je buď zahozena, nebo uložena v historii pro audit.
Client-side timestamp má nevýhodu: hodiny na zařízeních uživatelů mohou být desynchronizované. Pokud telefon uživatele A zaostává o 5 minut a uživatel B provede změny, záznam A může být po opravě hodin chybně považován za novější. Produkční systémy proto častěji používají server-side timestamp, přiřazovaný serverem při příjmu dat.
Logika LWW se server-side timestamp:
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
}
Funkce resolveLWW přijímá dva dokumenty a vrací ten s větším timestampem. Při rovnosti obvykle vítězí příchozí dokument — to zaručuje, že nová data nejsou ztracena kvůli shodě razítek.
Hlavní výhodou LWW je algoritmická jednoduchost. Strategie nevyžaduje ukládání historie verzí, analýzu změn na úrovni polí ani řešení složitých konfliktů. Server zpracuje konflikt v jediné porovnávací operaci, což činí LWW nejrychlejší strategií. Ve Firebase Realtime Database zpracovává LWW až 100 tisíc konfliktů za sekundu na jednom uzlu.
Hlavní nevýhoda — ztráta dat při nezávislých změnách různých polí. Pokud uživatel A změnil název úkolu a uživatel B popis, LWW jednu z verzí zcela zahodí, ačkoli obě změny měly být zachovány. To je obzvlášť kritické pro formuláře, profily a konfigurace, kde záleží na každém poli.
Srovnání LWW s alternativními strategiemi:
| Charakteristika | LWW | Merge | CRDT |
|---|---|---|---|
| Složitost | Nízká | Střední | Vysoká |
| Ztráta dat | Ano | Minimální | Ne |
| Výkon | Vysoký | Střední | Střední |
| Historie verzí | Není vyžadována | Vyžadována | Vyžadována |
| Determinismus | Ano | Závisí na implementaci | Ano |
Podívejme se na implementaci LWW v kontextu mobilní aplikace pro nákupní seznam, kde několik členů rodiny může přidávat a označovat produkty offline. Každý prvek seznamu ukládá ID, název, stav a časové razítko poslední aktualizace. Při synchronizaci je LWW aplikován na každý prvek.
Základní model prvku seznamu:
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
}
Funkce syncWithLWW slučuje lokální a vzdálené seznamy: pokud prvek existuje pouze na jedné straně — je přidán, pokud na obou — vítězí novější verze. Tento přístup zajišťuje deterministickou synchronizaci pro každý jednotlivý prvek.
Volba mezi LWW a Merge je určena povahou modifikace dat. Pokud aplikace umožňuje nezávislé změny polí (různí uživatelé mění různá pole stejného objektu), Merge Strategy data přesněji zachová. Pokud jsou změny vždy atomické (uživatel mění celý objekt), LWW je zcela adekvátní a výrazně jednodušší na implementaci.
V praxi mnoho systémů používá hybridní přístup: LWW pro meta-informace a pole horní úrovně, Merge pro strukturovaná data. Firebase Firestore například používá LWW pro většinu operací, ale podporuje transakce s optimistickým zamykáním pro atomické aktualizace, když vývojář výslovně určí, že pole nesmí být při konfliktu ztraceno.
Podle průzkumu mezi vývojáři distribuovaných systémů (Stack Overflow Survey, 2025) volí 54 % LWW pro MVP a prototypy, přecházejíce na Merge nebo CRDT ve fázi škálování. Klíčovým kritériem je frekvence konfliktů: pokud méně než 1 % sezení vede ke konfliktům, LWW je více než dostačující. Pokud konflikty ovlivňují více než 5 % sezení, stojí za to investovat do Merge nebo CRDT.
Často kladené otázky
Last Write Wins (LWW) — strategie řešení konfliktů, při které se ze dvou konkurenčních verzí vybírá záznam s nejnovějším časovým razítkem. Je to nejjednodušší mechanismus konvergence používaný ve Firebase, Cassandra a DynamoDB.
LWW se používá ve Firebase Realtime Database, Apache Cassandra, Riak KV, Amazon DynamoDB (režim posledního zápisu) a CouchDB pro pole horní úrovně. Většina dokumentově orientovaných NoSQL databází aplikuje LWW standardně.
Ano, ztráta dat je možná. Pokud dva uživatelé změnili různá pole stejného objektu, LWW zahodí starší verzi úplně i se všemi jejími změnami. Pro nezávislá pole je preferovaná Merge Strategy nebo CRDT.
Pro minimalizaci ztrát používejte server-side timestamp, uchovávejte historii verzí pro audit a aplikujte LWW pouze na data, kde je poslední verze objektivně správná. Pro strukturovaná pole zvažte Merge Strategy na úrovni polí.
Dopad je minimální. LWW vyžaduje pouze porovnání dvou číselných hodnot (O(1)), což z něj činí nejrychlejší strategii. Firebase Realtime Database zpracovává až 100 tisíc konfliktů za sekundu na jednom uzlu bez znatelného snížení výkonu.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.