{
    "slug": "vector_clock",
    "term": "Vector Clocks — Distributed Causality",
    "category": "architecture",
    "difficulty": "advanced",
    "short": "A vector clock is a data structure — one counter per node — that tracks causal ordering of events across distributed nodes without a shared clock, enabling detection of concurrent events and causal relationships.",
    "long": "Physical clocks on different machines drift and cannot reliably order events. A vector clock assigns each node an integer counter. When a node processes an event it increments its own counter. When it sends a message, it attaches its current vector. On receiving a message, the recipient merges the vectors by taking the maximum of each position, then increments its own. Given two vector clocks VC(A) and VC(B): if every position of VC(A) is ≤ VC(B) and at least one is strictly less, A causally precedes B. If neither dominates the other, the events are concurrent — no causal relationship exists. Amazon Dynamo used vector clocks for conflict detection. DynamoDB, Riak, and many distributed databases use vector clock variants.",
    "aliases": [
        "vector clock",
        "Lamport timestamp",
        "logical clock",
        "causal ordering"
    ],
    "tags": [
        "distributed-systems",
        "causality",
        "consistency",
        "clocks"
    ],
    "misconception": "Lamport timestamps are the same as vector clocks. Lamport timestamps are scalar — they provide a total order but cannot detect concurrency. Vector clocks are per-node — they can detect when two events are truly concurrent (neither happened before the other).",
    "why_it_matters": "Distributed systems cannot rely on wall-clock time to order events — NTP synchronisation has millisecond-level drift and events that happen 'at the same time' on different nodes cannot be ordered. Vector clocks provide a mathematically correct way to determine 'A happened before B' or 'A and B happened concurrently', which is essential for conflict detection in eventually consistent databases.",
    "common_mistakes": [
        "Using Lamport timestamps when you need concurrency detection — scalar Lamport clocks provide ordering but cannot tell you two events were concurrent.",
        "Not including the vector clock when sending messages — causality is only tracked if the clock travels with the data.",
        "Unbounded vector clock growth — in systems with many nodes, vectors grow indefinitely; use version vectors or bounded variants for production.",
        "Conflating 'concurrent' with 'conflicting' — concurrent events are not necessarily in conflict; application logic determines whether a conflict needs resolution."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "crdt",
        "raft_consensus",
        "eventual_consistency",
        "cap_theorem",
        "distributed_tracing"
    ],
    "prerequisites": [],
    "refs": [
        "https://en.wikipedia.org/wiki/Vector_clock",
        "https://lamport.azurewebsites.net/pubs/time-clocks.pdf"
    ],
    "bad_code": "// ❌ Using wall-clock timestamps to order distributed events\n$event = [\n    'data'      => $payload,\n    'timestamp' => microtime(true), // Different servers have different clocks\n];\n// Events from two nodes with 50ms clock skew cannot be ordered correctly\n// 'Last write wins' based on this timestamp loses causally later updates",
    "good_code": "<?php\n// ✅ Vector clock implementation\nclass VectorClock\n{\n    private array $clock = []; // nodeId => counter\n\n    public function increment(string $nodeId): void\n    {\n        $this->clock[$nodeId] = ($this->clock[$nodeId] ?? 0) + 1;\n    }\n\n    public function merge(VectorClock $other): VectorClock\n    {\n        $merged = clone $this;\n        foreach ($other->clock as $nodeId => $count) {\n            $merged->clock[$nodeId] = max($merged->clock[$nodeId] ?? 0, $count);\n        }\n        return $merged;\n    }\n\n    public function isConcurrentWith(VectorClock $other): bool\n    {\n        $aLessB = false;\n        $bLessA = false;\n        $allNodes = array_unique(array_merge(array_keys($this->clock), array_keys($other->clock)));\n        foreach ($allNodes as $node) {\n            $a = $this->clock[$node] ?? 0;\n            $b = $other->clock[$node] ?? 0;\n            if ($a < $b) $aLessB = true;\n            if ($b < $a) $bLessA = true;\n        }\n        return $aLessB && $bLessA; // Neither dominates → concurrent\n    }\n}",
    "quick_fix": "In PHP distributed systems, use a causal consistency library or a database (Riak, Cassandra with client-side timestamps) that handles vector clocks for you rather than implementing them manually.",
    "effort": "high",
    "created": "2026-03-23",
    "updated": "2026-03-23",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/vector_clock",
        "html_url": "https://codeclaritylab.com/glossary/vector_clock",
        "json_url": "https://codeclaritylab.com/glossary/vector_clock.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Vector Clocks — Distributed Causality](https://codeclaritylab.com/glossary/vector_clock) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/vector_clock"
            }
        }
    }
}