Each process P maintains a vector clock V[P], a counter per process. On a local event:
V[P] += 1. On send: include current V. On receive: V = max(V, V_received); V[P] += 1.
Two events A and B are concurrent iff neither V_A ≤ V_B nor V_B ≤ V_A. Otherwise one causally precedes the other. This distinguishes "happened before" from "happened at the same time".