Counter — Go Benchmark
A benchmark to compare the performance of different counter implementations in Go.
Compares different ways to implement a counter in Go, from a plain integer to thread-safe variants using atomics or a mutex. The basic int counter serves as a non-synchronized baseline, while atomic.Uint64, atomic.AddUint64, and sync.Mutex each add safety at different performance costs.
1 CPU
Fastest
Int CounterSlowest
Int Counter With MutexFastest
Int CounterSlowest
Int Counter With Mutex32 CPUs
Fastest
Atomic Uint CounterSlowest
Int Counter With MutexFastest
Int CounterSlowest
Int Counter With MutexInt Counter
Fastest (Get, 1 CPU)Fastest (Increment)A plain uint64 counter incremented with c.count++. Not thread-safe — serves as a baseline to show the raw cost of incrementing without any synchronization.
Atomic Pointer Counter
Uses a raw uint64 field and the free-function atomic.AddUint64 / atomic.LoadUint64 API, passing a pointer to the field explicitly. This is the pre-Go-1.19 style of atomic access.
Atomic Uint Counter
Fastest (Get, 32 CPUs)Uses atomic.Uint64 (introduced in Go 1.19) which wraps atomic operations behind method calls (Add, Load). Functionally equivalent to the pointer variant but with a cleaner API.
Int Counter With Mutex
Slowest (Get)Slowest (Increment)Wraps a plain uint64 counter with a sync.Mutex, locking on every increment and get call. Thread-safe, but the mutex adds overhead compared to lock-free atomic operations.
Contributors