Skip to content

A race condition exists when correctness depends on which concurrent operation happens first.

sequenceDiagram
    participant A as Worker A
    participant S as Shared state
    participant B as Worker B
    A->>S: Read value = 10
    B->>S: Read value = 10
    A->>S: Write value = 11
    B->>S: Write value = 11
    Note over A,B: One update is lost

The problem is not concurrency by itself. The problem is that the invariant depends on an unsafe interleaving.

Failures are intermittent, load-dependent, or difficult to reproduce. Lost updates, duplicated work, invalid state transitions, and stale decisions are common outcomes.

Use stress tests, deterministic concurrency tests where possible, tracing with operation identifiers, and review of shared mutable state. Reproduce the invariant that was violated rather than relying only on timing.

Protect shared state with an appropriate synchronization or serialization mechanism. Database transactions, optimistic concurrency control, locks, queues, immutable state, or idempotent operations can each fit different boundaries.

Stronger serialization can reduce throughput or increase contention. Lock-free or highly concurrent designs can improve throughput while increasing reasoning cost.

Do not add synchronization without defining the invariant that it protects.

  • Maurice Herlihy and Nir Shavit. The Art of Multiprocessor Programming.