Causally-ordered timestamps for deterministic conflict resolution
The Hybrid Logical Clock (HLC) is the foundation of GenosDB’s conflict resolution system. It provides causally-ordered, monotonic timestamps for all operations, ensuring that conflict resolution is deterministic, reliable, and immune to physical clock desynchronization.
When a node receives data from a peer, it synchronizes its local clock with the remote timestamp.
class HybridClock { update(remoteTimestamp) { const wallTime = Date.now(); // Take maximum of local and remote physical time const newPhysical = Math.max( wallTime, this.state.physical, remoteTimestamp.physical ); // Update logical component if (newPhysical === this.state.physical && newPhysical === remoteTimestamp.physical) { // Same millisecond for all three, take max logical + 1 this.state.logical = Math.max( this.state.logical, remoteTimestamp.logical ) + 1; } else if (newPhysical === this.state.physical) { // Same as local physical, increment local logical this.state.logical++; } else if (newPhysical === remoteTimestamp.physical) { // Same as remote physical, use remote logical + 1 this.state.logical = remoteTimestamp.logical + 1; } else { // Physical time advanced, reset logical this.state.logical = 0; } this.state.physical = newPhysical; }}
This synchronization protocol ensures the local clock always “learns” from remote events, propagating causal information through the network.
When comparing two timestamps to determine which is “later”:
function compareTimestamps(t1, t2) { // 1. Compare physical components first if (t1.physical > t2.physical) return 1; // t1 is later if (t1.physical < t2.physical) return -1; // t2 is later // 2. Physical components equal, compare logical if (t1.logical > t2.logical) return 1; // t1 is later if (t1.logical < t2.logical) return -1; // t2 is later return 0; // Timestamps are identical}
1
Compare Physical
The timestamp with the greater physical value wins
2
Compare Logical (if tied)
If physical values are equal, the timestamp with the greater logical value wins
3
Deterministic Tie-Breaking
If both components are equal, timestamps are identical (very rare)
async function put(value) { const id = generateId(); const timestamp = this.hybridClock.now(); const node = { id, value, timestamp, lastModifiedBy: this.currentUser }; // Write to local graph this.graph.set(id, node); // Log operation this.oplog.append({ type: 'upsert', id, timestamp }); // Broadcast to network if (this.rtcEnabled) { this.syncChannel.send({ type: 'operation', operation: node }); } return id;}
2. Remote Update Reception
function handleRemoteUpdate(operation) { // Resolve conflict const { winner, node } = resolveConflict( this.graph.get(operation.id), operation ); if (winner === 'remote') { // Update local graph this.graph.set(operation.id, node); // Sync clock with winning timestamp this.hybridClock.update(node.timestamp); // Trigger reactivity this.notifySubscribers(operation.id, node); } // else: local wins, discard remote}
3. Full-State Sync
function applyFullState(remoteGraph) { for (const [id, remoteNode] of remoteGraph) { const { winner, node } = resolveConflict( this.graph.get(id), remoteNode ); if (winner === 'remote') { this.graph.set(id, node); this.hybridClock.update(node.timestamp); } } // Update global timestamp to max seen const maxTimestamp = findMaxTimestamp(this.graph); this.globalTimestamp = maxTimestamp;}
After accepting a remote update, the local HLC is synchronized with the winning timestamp. This ensures the local node has “fast-forwarded” its clock, maintaining causal consistency.
// Peer A (physical: 1000)db.put({ id: 'task-1', text: 'Buy milk' });// Timestamp: { physical: 1000, logical: 0 }// Peer B (physical: 1000, same millisecond!)db.put({ id: 'task-1', text: 'Buy eggs' });// Timestamp: { physical: 1000, logical: 0 }// When they sync:// Both have same physical time, but B's update came slightly after// B's logical counter would be incremented on sync// Final result: { physical: 1000, logical: 1 } -> "Buy eggs" wins
While HLC tolerates clock skew, extreme differences (hours/days) can cause unexpected LWW outcomes. Use NTP or similar time synchronization on devices when possible.
Don't Rely on Physical Time for Ordering
HLC provides causal ordering, not real-world time ordering. Don’t assume timestamp.physical reflects actual creation time for sorting purposes.
Monitor for Future Drift
If you see many sanitized timestamps in logs, investigate system clock configuration on clients.
Understand LWW Semantics
Last-Write-Wins means some updates may be discarded. Design your data model accordingly (e.g., use append-only patterns for critical data).