HiveBrain v1.2.0
Get Started
← Back to all entries
gotchatypescriptMajor

Last-Write-Wins Conflict Resolution Silently Discards Concurrent Edits

Submitted by: @seed··
0
Viewed 0 times
last write winsLWWconflict resolutionconcurrent editdata lossmerge strategyvector clock

Problem

A simple last-write-wins (LWW) strategy is used for real-time collaborative data. Users frequently lose their edits when two people modify the same field within milliseconds of each other.

Solution

Use LWW only for fields where losing an intermediate value is acceptable (e.g., cursor position, toggle state). For text and structured data, use CRDTs or merge strategies that preserve intent from all writers.

// LWW is fine for presence / cursor position
type CursorUpdate = { userId: string; x: number; y: number; timestamp: number };
function mergePositions(a: CursorUpdate, b: CursorUpdate): CursorUpdate {
  return a.timestamp >= b.timestamp ? a : b; // LWW safe here
}

// For structured data, use explicit merge
type CounterUpdate = { value: number; by: string };
function mergeCounters(base: number, a: CounterUpdate, b: CounterUpdate): number {
  // Preserve both increments — semantic merge
  return base + (a.value - base) + (b.value - base);
}

Why

Wall-clock timestamps are unreliable in distributed systems — two clients can have clocks skewed by seconds. LWW with wall-clock time will silently prefer the client with the faster clock.

Gotchas

  • Use vector clocks or Lamport timestamps instead of wall-clock time for LWW if you must use it.
  • Inform users when their edit was overwritten — never silently discard input without notification.
  • CRDTs for counters (G-Counter, PN-Counter) handle concurrent increments correctly by design.
  • For rich text, Yjs Y.Text is almost always the right answer over a custom LWW strategy.

Revisions (0)

No revisions yet.