Backend Development 18 min read

Analysis of Go's sync.Map Implementation: Design, Architecture, and Source Code Walkthrough

The article explains how Go’s sync.Map achieves high‑concurrency performance by maintaining a lock‑free read‑only snapshot in an atomic.Value and a mutex‑protected dirty map, detailing entry state transitions, miss‑driven promotion, and the Store, Load, and Delete operations that together avoid a global lock.

Tencent Cloud Developer
Tencent Cloud Developer
Tencent Cloud Developer
Analysis of Go's sync.Map Implementation: Design, Architecture, and Source Code Walkthrough

Background: In high‑concurrency scenarios the native Go map is not safe for concurrent reads/writes, leading to panic. Two solutions are presented: using a sync.Mutex / sync.RWMutex (simple but slower) or using sync.Map , introduced in Go 1.9.

The article analyzes why sync.Map can achieve high performance without a global lock, by combining atomic operations and mutexes.

Core Idea & Architecture

sync.Map maintains two internal maps: a read‑only map ( read ) and a dirty map ( dirty ). The read map is stored in an atomic.Value and can be accessed without locking, providing fast reads. The dirty map holds all keys that are not yet present in the read map and is protected by a sync.Mutex .

Read map: snapshot, accessed atomically, may not contain newly added keys.

Dirty map: full key set, protected by lock, used when a key is missing from the read map.

Miss counter triggers promotion of dirty to read when reads miss frequently.

Entries are wrapped in an entry struct whose p field can be nil , expunged , or a normal pointer. This allows logical deletion without immediate removal.

Key Operations

Store (C/U)

func (m *Map) Store(key, value interface{}) {
    read, _ := m.read.Load().(readOnly)
    if e, ok := read.m[key]; ok && e.tryStore(&value) {
        return
    }
    m.mu.Lock()
    // ... handle read, dirty, create new entry, etc.
    m.mu.Unlock()
}

func (e *entry) tryStore(i *interface{}) bool { /* CAS logic */ }
func (e *entry) unexpungeLocked() (wasExpunged bool) { /* CAS */ }
func (e *entry) storeLocked(i *interface{}) { /* atomic store */ }
func (m *Map) dirtyLocked() { /* initialize dirty from read */ }
func (e *entry) tryExpungeLocked() (isExpunged bool) { /* turn nil into expunged */ }

Load (R)

func (m *Map) Load(key interface{}) (value interface{}, ok bool) {
    read, _ := m.read.Load().(readOnly)
    e, ok := read.m[key]
    if !ok && read.amended {
        m.mu.Lock()
        // ... check dirty, increment miss counter
        m.mu.Unlock()
    }
    if !ok {
        return nil, false
    }
    return e.load()
}

func (m *Map) missLocked() { /* promote dirty to read when misses exceed threshold */ }
func (e *entry) load() (value interface{}, ok bool) { /* atomic load */ }

Delete (D)

func (m *Map) Delete(key interface{}) {
    m.LoadAndDelete(key)
}

func (m *Map) LoadAndDelete(key interface{}) (value interface{}, loaded bool) {
    // similar to Load, then remove entry
}

func (e *entry) delete() (value interface{}, ok bool) { /* CAS to nil */ }

The article also discusses state transitions of entry.p (nil → expunged, normal pointer), the conditions for read‑to‑dirty and dirty‑to‑read promotion, and the rationale behind having both nil and expunged states.

Overall Thoughts

sync.Map ’s design cleverly balances lock‑free reads with occasional locked writes, using atomic snapshots and a dirty map to minimise contention while preserving correctness. Understanding these mechanisms helps developers choose the right concurrency primitive for high‑throughput Go services.

PerformanceConcurrencyGomapData Structuressync.MapAtomic
Tencent Cloud Developer
Written by

Tencent Cloud Developer

Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.