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.