Skip to main content

Atomics vs Mutexes

Simple guideline

Start with mutexes (clearer, safer). Only switch to atomics if profiling shows a performance bottleneck and the shared state is simple enough.

Atomics

Atomics (from sync/atomic) provide low-level, lock-free, single-variable operations.

  • What they do:

  • When to use:

    • Protecting a single counter/flag/state variable.

      var counter int64
      atomic.AddInt64(&counter, 1)
    • Implementing lock-free algorithms.

    • Fast-path optimizations where contention is low.

    • Performance-critical code where avoiding the overhead of a mutex matters.

  • Advantages:

    • Very fast (no kernel call, no blocking).
    • Scales well under high contention if operations are simple.
  • Disadvantages:

    • Limited to simple operations (no complex invariants).
    • Easy to misuse → subtle bugs, memory-ordering issues.
    • Code harder to read/maintain.

Mutexes

Mutexes (sync.Mutex, sync.RWMutex) provide higher-level mutual exclusion.

  • What they do:

    • Lock a critical section so only one goroutine can enter at a time.
    • RWMutex allows multiple readers, but only one writer.
  • When to use:

    • Protecting compound state (structs, maps, slices).

      var mu sync.Mutex
      m := make(map[string]int)

      mu.Lock()
      m["a"]++
      mu.Unlock()
      • When multiple variables need to be updated consistently (atomic can’t ensure invariants).
      • When correctness and clarity are more important than raw performance.
  • Advantages:

    • Easy to reason about.
    • Works for complex invariants, multiple fields.
    • Safer and clearer than atomics in most cases.
  • Disadvantages:

    • Slower than atomics (involves locking/unlocking).
    • Can cause contention and blocking.
    • Deadlocks possible if misused.

Summary

  • Use atomics for:
    • Simple counters, flags, or single shared integers/pointers.
    • Performance-critical hot paths.
  • Use mutexes for:
    • Protecting composite data structures.
    • Ensuring consistency across multiple variables.
    • Most cases where correctness matters more than raw speed.