# Highly concurrent in-memory counter in GoLang

[Grab](https://yomu.fyi/company/grab) · Naveen Kumar Jakuva Premkumar · Oct 6, 2025

## Summary

High database CPU utilization caused by relentless write traffic for marketing campaign counts prompted Grab to build an in-memory aggregation buffer rather than migrate from SQL to NoSQL. The team implemented an in-memory counter in Go that batches usage updates and periodically flushes them to persistent storage. To eliminate the serialization bottlenecks of mutex-locked maps under high concurrency, the design adopted Go's sync.Map using atomic CompareAndSwap retries for value updates alongside LoadAndDelete for periodic background flushes. Because a finite set of campaign keys is repeatedly accessed, operations hit the internal read map fast path nearly 99% of the time, achieving a threefold throughput improvement over standard mutex locks in benchmarks. In production, this architecture decreased database update queries by 68% and reduced master database CPU utilization from 35% to 18%.

## Takeaways

- Using sync.Map with atomic CompareAndSwap retry loops enables lock-free concurrent updates on existing keys, delivering roughly three times higher throughput than sync.RWMutex in benchmarks with 2,000 keys.
- Flushing in-memory counters via sync.Map's LoadAndDelete extracts and removes key values atomically without locking the entire map or blocking concurrent increments.
- Buffering non-critical approximate counters in application memory cut production database update traffic from 140 QPS to 45 QPS and lowered master CPU utilization by 48.5%.

**Tags:** [Caching](https://yomu.fyi/topic/caching), [Go](https://yomu.fyi/topic/go), [Performance](https://yomu.fyi/topic/performance), [Scalability](https://yomu.fyi/topic/scalability)

[Read original post](https://engineering.grab.com/highly-concurrent-in-memory-counter-in-go-lang)
