DevTools Hub

Search tools

Search for a developer tool

Distributed Systems

Vector Clock Conflict Simulator

Simulate last-write-wins vs vector clocks resolving a concurrent write — see when clock skew silently drops data.

Part of the Distributed Systems Toolkit
Last-write-wins: keeps Node A
Node B's write was genuinely later in real time, but its skewed timestamp made Node A's look newer — it's silently gone, with no conflict ever flagged.
Vector clock: flags as concurrent
Neither write observed the other, so it's reported as a genuine conflict and both versions are kept for the application to merge — nothing is silently dropped.
TimeActorEventDetail
t=0msNode AWritesLocal clock reads 0ms — used here as the true-time reference
t=2000msNode BWritesLocal clock reads -3000ms (skew -5000ms) — real time is 2000ms after Node A's write
t=2000msLWWCompares timestampsNode A's timestamp (0ms) vs Node B's timestamp (-3000ms) — keeps Node A
t=2000msLWWSilently discards Node B's writeNo conflict is ever flagged — Node B's genuinely later write is simply gone
t=2000msVector ClockDetects a concurrent writeNeither vector dominates the other — the writes are genuinely concurrent, not an order either node's clock can resolve
t=2000msVector ClockKeeps both as siblingsBoth versions are handed to the application to merge — nothing is silently discarded

What this simulates

Two replicas each get written to around the same time — Node A, then Node B some number of milliseconds later in real time. Something has to decide which write "wins" once the two replicas compare notes. This tool runs that same conflict through two different resolution strategies: last-write-wins, which trusts each node's own wall clock, and a vector clock, which tracks causality instead — and shows exactly when the two disagree.

Why a correct clock on every node still isn't enough

Last-write-wins sounds reasonable: attach a timestamp to every write, keep the newest one. The problem is that "newest" is only as reliable as the clocks doing the comparing, and real machines' clocks are never perfectly synchronized. Set Node B's clock skew negative enough in this tool and you'll see it happen directly: Node B's write is genuinely the later one in real time, but its slow clock makes it look older than Node A's, so LWW silently keeps Node A's write instead. There's no error, no retry, no conflict logged anywhere — the real last write is just gone, which is exactly the failure mode Eventual Consistency Explained walks through.

How a vector clock avoids the same mistake

A vector clock never looks at wall-clock time at all — it tracks, per node, which writes each replica has actually observed. Toggle "Node B had already seen Node A's write" on, and the vector clock correctly orders B after A regardless of what either clock says, because it has a real causal link to go on. Leave it off, and the two writes never observed each other — so instead of guessing, the vector clock honestly reports a conflict and keeps both versions as siblings for the application to merge. That second case is the one a naive system builder might assume should also pick a winner — it shouldn't, because there genuinely isn't one to pick.

FAQ

Is anything sent anywhere?

No — this is a deterministic, client-side simulation. Nothing leaves your browser.

Does a vector clock always refuse to pick a winner?

No — when one write genuinely happened after observing the other (the causally-dependent case in this tool), the vector clock resolves it cleanly with no ambiguity at all. It only reports "concurrent" when that's actually true, which is the entire point: it never confidently returns a wrong answer the way a skewed wall clock can.

What happens to the two sibling versions a vector clock keeps?

That's pushed up to the application, which usually has domain-specific logic LWW can never have — Dynamo's own example is a shopping cart, where the right "merge" is often just the union of both carts' items, not an arbitrary pick between them.

Is this the same mechanism as a CRDT?

Related, not identical. A vector clock only detects and surfaces a conflict; a CRDT is a data structure specifically designed so that merge step is automatic and deterministic — see Eventual Consistency Explained for how G-Counters and OR-Sets do that for counters and sets.

How does this relate to the Distributed Lock Simulator?

Both are concurrency hazards with the same root cause — not every node agrees on "what happened when." Distributed Lock Simulator covers it for exclusive access to one resource; this tool covers it for two replicas of the same data being written to independently.

Related tools